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
Strong and weak references in Swift
提问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?
来源: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 使用的更多信息
- Kaan Dedeogluanswer
- ARC and Memory Management in Swift
- "WEAK, STRONG, UNOWNED, OH MY!" - A GUIDE TO REFERENCES IN SWIFT
- ARC Swift Tutorial
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

