Swift中的强引用和弱引用

49

在 Objective C 中,你可以像这样定义一个具有强引用或弱引用的属性:

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

在Swift中如何实现这个?

6个回答

67

直接来自Swift语言指南

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


6
"unowned" 不等同于 Objective-C 中的 "unsafe_unretained"。 - user102008

12

变量默认为strong。您可以在变量前添加weak关键字使其变为weak。


11

5

我是一名有用的助手,可以为您提供文本翻译。

这是一条更重要的评论,但我无法放进去。

如果你这样做

weak let name : SomeClass

它会出现以下错误:

'weak'必须是可变变量,因为它可能在运行时更改

你必须执行以下操作:

weak var name : SomeClass

“weak”变量应该具有可选类型“SomeClass?”

所以你必须这样做:

weak var name : SomeClass?

此外,在Swift中,所有弱引用都是非常量可选项(考虑var vs. let),因为当没有任何东西持有强引用时,引用可以并将被更改为nil。请参见这里
由于这种强制的可选性,您总是需要对其进行解包,以便访问其实际值。

@ChrisPrince 通常不建议使用隐式解包可选项,但是你也可以这样做... - mfaani
我们可以选择在这一点上持不同意见。同时,也可以看一下Swift中的IBOutlet成员变量。 - Chris Prince

4

仅想让您知道,“var”默认情况下是“强引用”,但在其前面添加“weak”可使其变为“弱引用”。如果您错过了这一点


1

详情

  • Xcode 11.3.1,Swift 5.1

有关ARC使用的更多信息

完整示例

import Foundation

class BasicClass: CustomStringConvertible {
    private var objectName: String
    init(objectName: String) { self.objectName = objectName; print ("INITED \(self)") }
    deinit { print ("DEINITED \(self)") }
    var description: String { return "\"\(objectName)\" of \"\(type(of: self))\", with \(referenceCountInfo)" }
    var referenceCountInfo: String { return "reference count to self: \(CFGetRetainCount(self))" }
}

class Class1: BasicClass {
    var objectWithStrongReference: Class2?
    override var description: String {
        return super.description + "\n -- nested obj with strong reference: \(objectWithStrongReference?.referenceCountInfo ?? "nil")"
    }
}

class Class2: BasicClass {
    weak var objectWithWeakReference: Class1?
    override var description: String {
        return super.description + "\n -- nested obj with weak reference: \(objectWithWeakReference?.referenceCountInfo ?? "nil")"
    }
}

var obj1: Class1? = Class1(objectName: "obj1")
var obj2: Class2? = Class2(objectName: "obj2")

print("\n=====================================")
print("obj1.value = obj2, obj2.value = obj1")
obj1?.objectWithStrongReference = obj2
obj2?.objectWithWeakReference = obj1
print(obj1 ?? "nil")
print(obj2 ?? "nil")
print("\n=====================================")
print("obj2 = nil")
obj2 = nil
print(obj1 ?? "nil")
print(obj2 ?? "nil")

print("\n=====================================")
print("obj1 = nil")
obj1 = nil
print(obj1 ?? "nil")
print(obj2 ?? "nil")

日志

INITED "obj1" of "Class1", with reference count to self: 3
 -- nested obj with strong reference: nil
INITED "obj2" of "Class2", with reference count to self: 3
 -- nested obj with weak reference: nil

=====================================
obj1.value = obj2, obj2.value = obj1
"obj1" of "Class1", with reference count to self: 6
 -- nested obj with strong reference: reference count to self: 4
"obj2" of "Class2", with reference count to self: 7
 -- nested obj with weak reference: reference count to self: 3

=====================================
obj2 = nil
"obj1" of "Class1", with reference count to self: 6
 -- nested obj with strong reference: reference count to self: 3
nil

=====================================
obj1 = nil
DEINITED "obj1" of "Class1", with reference count to self: 3
 -- nested obj with strong reference: reference count to self: 3
DEINITED "obj2" of "Class2", with reference count to self: 3
 -- nested obj with weak reference: nil
nil
nil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接