Swift-ARCの概要
メモリ管理機能とその使用法は、自動参照カウント(ARC)を介してSwift4言語で処理されます。ARCは、システムリソースを初期化および非初期化するために使用され、インスタンスが不要になったときにクラスインスタンスによって使用されていたメモリスペースを解放します。ARCは、メモリリソースを効果的に管理するために、コードインスタンス間の関係に関する情報を追跡します。
ARCの機能
ARCは、init()によって新しいクラスインスタンスが作成されるたびに、情報を格納するためのメモリのチャンクを割り当てます。
インスタンスタイプとその値に関する情報はメモリに保存されます。
クラスインスタンスが不要になると、deinit()によってメモリスペースが自動的に解放され、クラスインスタンスをさらに保存および取得できるようになります。
ARCは、現在参照しているクラスインスタンスのプロパティ、定数、および変数を追跡し、deinit()がそれらの未使用のインスタンスにのみ適用されるようにします。
ARCは、これらのクラスインスタンスのプロパティ、定数、および変数への「強力な参照」を維持して、クラスインスタンスが現在使用されているときに割り当て解除を制限します。
ARCプログラム
class StudDetails {
var stname: String!
var mark: Int!
init(stname: String, mark: Int) {
self.stname = stname
self.mark = mark
}
deinit {
print("Deinitialized \(self.stname)")
print("Deinitialized \(self.mark)")
}
}
let stname = "Swift 4"
let mark = 98
print(stname)
print(mark)
遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-
Swift 4
98
ARCストロングリファレンスサイクルクラスインスタンス
class studmarks {
let name: String
var stud: student?
init (name: String) {
print("Initializing: \(name)")
self.name = name
}
deinit {
print("Deallocating: \(self.name)")
}
}
class student {
let name: String
var strname: studmarks?
init (name: String) {
print("Initializing: \(name)")
self.name = name
}
deinit {
print("Deallocating: \(self.name)")
}
}
var shiba: studmarks?
var mari: student?
shiba = studmarks(name: "Swift 4")
mari = student(name: "ARC")
shiba!.stud = mari
mari!.strname = shiba
遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-
Initializing: Swift 4
Initializing: ARC
ARCの弱い参照と所有されていない参照
クラスタイプのプロパティには、強力な参照サイクルを解決する2つの方法があります-
- 弱い参照
- 所有されていない参照
これらの参照は、1つのインスタンスが参照サイクルで他のインスタンスを参照できるようにするために使用されます。次に、インスタンスは、強力な参照サイクルを気にする代わりに、すべてのインスタンスを参照する場合があります。一部のインスタンスが「nil」値を返す可能性があることをユーザーが知っている場合、弱参照を使用してそれを指摘することがあります。インスタンスがnilではなく何かを返す場合は、所有されていない参照で宣言します。
弱参照プログラム
class module {
let name: String
init(name: String) { self.name = name }
var sub: submodule?
deinit { print("\(name) Is The Main Module") }
}
class submodule {
let number: Int
init(number: Int) { self.number = number }
weak var topic: module?
deinit { print("Sub Module with its topic number is \(number)") }
}
var toc: module?
var list: submodule?
toc = module(name: "ARC")
list = submodule(number: 4)
toc!.sub = list
list!.topic = toc
toc = nil
list = nil
遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-
ARC Is The Main Module
Sub Module with its topic number is 4
所有されていない参照プログラム
class student {
let name: String
var section: marks?
init(name: String) {
self.name = name
}
deinit { print("\(name)") }
}
class marks {
let marks: Int
unowned let stname: student
init(marks: Int, stname: student) {
self.marks = marks
self.stname = stname
}
deinit { print("Marks Obtained by the student is \(marks)") }
}
var module: student?
module = student(name: "ARC")
module!.section = marks(marks: 98, stname: module!)
module = nil
遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-
ARC
Marks Obtained by the student is 98
閉鎖のための強力な参照サイクル
クラスインスタンスプロパティとクロージャの本体にクロージャを割り当てて特定のインスタンスをキャプチャすると、強力な参照サイクルが発生する可能性があります。クロージャーへの強い参照は、「self.someProperty」または「self.someMethod()」によって定義されます。クロージャの参照タイプとして、強力な参照サイクルが使用されます。
class HTMLElement {
let samplename: String
let text: String?
lazy var asHTML: () -> String = {
if let text = self.text {
return "<\(self.samplename)>\(text)</\(self.samplename)>"
} else {
return "<\(self.samplename) />"
}
}
init(samplename: String, text: String? = nil) {
self.samplename = samplename
self.text = text
}
deinit {
print("\(samplename) is being deinitialized")
}
}
var paragraph: HTMLElement? = HTMLElement(samplename: "p", text: "Welcome to Closure SRC")
print(paragraph!.asHTML())
遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-
<p>Welcome to Closure SRC</p>
弱くて所有されていない参照
クロージャとインスタンスが相互に参照する場合、ユーザーはクロージャ内のキャプチャを所有されていない参照として定義できます。その場合、ユーザーがインスタンスの割り当てを同時に解除することはできません。インスタンスがいつか「nil」値を返す場合、弱いインスタンスでクロージャを定義します。
class HTMLElement {
let module: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in
if let text = self.text {
return "<\(self.module)>\(text)</\(self.module)>"
} else {
return "<\(self.module) />"
}
}
init(module: String, text: String? = nil) {
self.module = module
self.text = text
}
deinit {
print("\(module) the deinit()")
}
}
var paragraph: HTMLElement? = HTMLElement(module: "Inside", text: "ARC Weak References")
print(paragraph!.asHTML())
paragraph = nil
遊び場を使用して上記のプログラムを実行すると、次の結果が得られます-
<Inside>ARC Weak References</Inside>
Inside the deinit()