Swiftの強参照と弱参照
Objective Cでは、次のようにプロパティを強参照または弱参照として定義できます。
@property(strong)...
@property(weak)...
これはどのように迅速に行われますか?
Swift Language guide から直接:
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
deinit { println("\(name) is being deinitialized") }
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
weak var tenant: Person?
deinit { println("Apartment #\(number) is being deinitialized") }
}
プロパティはデフォルトで強いです。しかし、クラス「Apartment」のテナントプロパティを見ると、弱いと宣言されています。また、unownedキーワードを使用することもできます。これは、Objective-Cからunsafe_unretainedに変換されます
https://iTunes.Apple.com/tr/book/Swift-programming-language/id881256329?mt=11
Varはデフォルトで強いです。 varの前にweakキーワードを追加して、弱くすることができます。
プロパティはデフォルトで強いですが、弱いプロパティが必要な場合は次のことができます。
weak var tenant: Person?
これはより重要なコメントですが、私はそれを納得させることができませんでした。
もしあなたがそうするなら
weak let name : SomeClass
次のエラーが発生します。
'weak'は実行時に変更される可能性があるため、可変変数である必要があります
しなければならない
weak var name : SomeClass
'weak'変数にはオプションの型 'SomeClass?'が必要です
だからあなたはする必要があります:
weak var name : SomeClass?
また、Swiftでは、参照が強い参照を保持するものがなくなったときに参照がnilに変更される可能性があるため、すべての弱い参照は定数ではありません(var vs letを考えてください)。 こちら をご覧ください
この必須のオプション化の結果として、実際の値にアクセスできるように、常にunwrapする必要があります。
Varがデフォルトで強いことを知ってほしかったのですが、その前に「弱」を追加することで、それを弱くします。逃した場合に備えて
詳細
xCode 9.1、Swift 4
ARCの使用に関する詳細情報
完全なサンプル
import UIKit
var str = "Hello, playground"
class BasicClass: CustomStringConvertible {
let text: String
init(text: String) { self.text = text }
deinit { print ("Object of the \"\(className)\" class deinited") }
var className: String {
return "\(type(of: self))"
}
var referenceCount: Int {
return CFGetRetainCount(self)
}
var description: String {
return "className: \(className), reference count: \(referenceCount)"
}
}
class Class1: BasicClass {
var objectWithStrongReference: Class2?
override var description: String {
return super.description + ", embed strong obj reference count: \(objectWithStrongReference?.referenceCount ?? 0)"
}
}
class Class2: BasicClass {
weak var objectWithWeakReference: Class1?
override var description: String {
return super.description + ", embed weak obj reference count: \(objectWithWeakReference?.referenceCount ?? 0)"
}
}
var obj1: Class1? = Class1(text: "String 1")
print(obj1 ?? "nil")
var obj2: Class2? = Class2(text: "String 2")
print(obj2 ?? "nil")
print("=====================================")
print("obj1.value = obj2, obj2.value = obj1")
obj1?.objectWithStrongReference = obj2
obj2?.objectWithWeakReference = obj1
print(obj1 ?? "nil")
print(obj2 ?? "nil")
print("=====================================")
print("obj2 = nil")
obj2 = nil
print(obj1 ?? "nil")
print(obj2 ?? "nil")
print("=====================================")
print("obj1 = nil")
obj1 = nil
print(obj1 ?? "nil")
print(obj2 ?? "nil")