objective-c Swift 中的强引用和弱引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24016527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:16:00  来源:igfitidea点击:

Strong and weak references in Swift

objective-creferenceweak-referencesswift

提问by 67cherries

In Objective C you can define a property as having a strong or weak reference like so:

在 Objective C 中,您可以将属性定义为具有强引用或弱引用,如下所示:

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

How is this done in swift?

这是如何快速完成的?

回答by Kaan Dedeoglu

Straight from the Swift Language guide:

直接来自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") }
}

properties are strong by default. But look at the tenant property of the class "Apartment", it is declared as weak. You can also use the unowned keyword, which translates to unsafe_unretained from Objective-C

属性默认是强的。但是看看“公寓”类的租户属性,它被声明为弱。您还可以使用 unowned 关键字,它从 Objective-C 转换为 unsafe_unretained

https://itunes.apple.com/tr/book/swift-programming-language/id881256329?mt=11

https://itunes.apple.com/tr/book/swift-programming-language/id881256329?mt=11

回答by Connor

A var is strong by default. You can add the weak keyword before a var to make it weak.

默认情况下,var 是强的。您可以在 var 之前添加 weak 关键字以使其变弱。

回答by CW0007007

Properties are strong by default, but if you want a weak property you can:

默认情况下,属性是强属性,但如果您想要弱属性,您可以:

    weak var tenant: Person?

Source: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html

来源:https: //developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html

回答by Honey

This is more of an important comment, but I couldn't fit it in.

这是一个更重要的评论,但我无法适应。

If you do

如果你这样做

weak let name : SomeClass

It will give the following error:

它将给出以下错误:

'weak' must be a mutable variable, because it may change at runtime

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

You must do

你必须做

weak var name : SomeClass

'weak' variable should have optional type 'SomeClass?'

'weak' 变量应该有可选类型 'SomeClass?'

So you must do:

所以你必须这样做:

weak var name : SomeClass?

Also, in Swift, all weak references are non-constant Optionals (think var vs. let) because the reference can and will be mutated to nil when there is no longer anything holding a strong reference to it. See here

此外,在 Swift 中,所有弱引用都是非常量的 Optionals(想想 var 与 let),因为当不再有任何东西持有对它的强引用时,引用可以并且将会被改变为 nil。看这里

As a result of this mandatory optional-ization, you always need to unwrapit so you can access its actual value.

作为这种强制性可选化的结果,您总是需要解开它,以便您可以访问它的实际值。

回答by nevva

Just wanted you to know that a var is strong by default but by adding "weak" in front of it you make it weak. In case you missed it

只是想让您知道 var 默认情况下是强的,但是通过在它前面添加“弱”,您会使其变弱。以防你错过了它

回答by Vasily Bodnarchuk

Details

细节

  • Xcode 11.3.1, Swift 5.1
  • Xcode 11.3.1,Swift 5.1

More info about ARC usage

有关 ARC 使用的更多信息

Full sample

完整样品

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

Logs

日志

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