web-dev-qa-db-ja.com

Swiftの強参照と弱参照

Objective Cでは、次のようにプロパティを強参照または弱参照として定義できます。

@property(strong)...
@property(weak)...

これはどのように迅速に行われますか?

45
67cherries

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

63
Kaan Dedeoglu

Varはデフォルトで強いです。 varの前にweakキーワードを追加して、弱くすることができます。

12
Connor

プロパティはデフォルトで強いですが、弱いプロパティが必要な場合は次のことができます。

    weak var tenant: Person?

ソース: https://developer.Apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html

10
CW0007007

これはより重要なコメントですが、私はそれを納得させることができませんでした。

もしあなたがそうするなら

weak let name : SomeClass

次のエラーが発生します。

'weak'は実行時に変更される可能性があるため、可変変数である必要があります

しなければならない

weak var name : SomeClass

'weak'変数にはオプションの型 'SomeClass?'が必要です

だからあなたはする必要があります:

weak var name : SomeClass?

また、Swiftでは、参照が強い参照を保持するものがなくなったときに参照がnilに変更される可能性があるため、すべての弱い参照は定数ではありません(var vs letを考えてください)。 こちら をご覧ください

この必須のオプション化の結果として、実際の値にアクセスできるように、常にunwrapする必要があります。

4
Honey

Varがデフォルトで強いことを知ってほしかったのですが、その前に「弱」を追加することで、それを弱くします。逃した場合に備えて

4
nevva

詳細

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")

結果

enter image description here

0