斯威夫特有:
强引用 弱引用 无主的引用
无主引用与弱引用有何不同?
什么时候使用无主引用是安全的?
无主引用是否像C/ c++中的悬浮指针一样存在安全风险?
斯威夫特有:
强引用 弱引用 无主的引用
无主引用与弱引用有何不同?
什么时候使用无主引用是安全的?
无主引用是否像C/ c++中的悬浮指针一样存在安全风险?
当前回答
Q1。“无主引用”与“弱引用”有何不同?
弱引用:
弱引用是指不能保持强引用的引用 它引用的实例,因此不会阻止ARC处理 引用的实例。因为弱引用是允许的 " no value "时,必须声明每个弱引用都具有 可选的类型。(苹果文档)
无主参考:
与弱引用一样,无主引用不会保持强持有 在它引用的实例上。然而,与弱引用不同的是 无主引用假定总是有一个值。正因为如此, 无主引用总是定义为非可选类型。(苹果文档)
何时使用:
只要该引用成为有效,就使用弱引用 在生命周期的某个时刻为Nil。相反,使用无主的 当你知道引用永远不会为nil时,再引用 已在初始化时设置。(苹果文档)
Q2。什么时候使用“无主引用”是安全的?
如上所述,假定无主引用总是有一个值。所以你应该只在确定引用永远不会为nil时使用它。Apple Docs通过以下示例演示了无主引用的用例。
假设我们有两个类Customer和CreditCard。客户可以没有信用卡而存在,但信用卡不会没有客户而存在,也就是说,可以假设信用卡总是有客户。所以,它们应该有这样的关系:
class Customer {
var card: CreditCard?
}
class CreditCard {
unowned let customer: Customer
}
第三季。在C/ c++中,“无主引用”引用是否像“悬空指针”一样存在安全风险
我不这么想。
由于无主引用只是保证有值的弱引用,因此无论如何都不应构成安全风险。然而,如果你试图访问一个无主引用后,它引用的实例被释放,你将触发一个运行时错误,应用程序将崩溃。
这是我看到的唯一风险。
链接到Apple Docs
其他回答
当你确定在你访问self时,self永远不会为nil时,使用u主。
示例(当然,你可以直接从MyViewController中添加目标,但同样,这是一个简单的例子):
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let myButton = MyButton { [unowned self] in
print("At this point, self can NEVER be nil. You are safe to use unowned.")
print("This is because myButton can not be referenced without/outside this instance (myViewController)")
}
}
}
class MyButton: UIButton {
var clicked: (() -> ())
init(clicked: (() -> ())) {
self.clicked = clicked
// We use constraints to layout the view. We don't explicitly set the frame.
super.init(frame: .zero)
addTarget(self, action: #selector(clicked), for: .touchUpInside)
}
@objc private func sendClosure() {
clicked()
}
}
当你访问self时,有可能self值为nil时,使用weak。
例子:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NetworkManager.sharedInstance.receivedData = { [weak self] (data) in
print("Can you guarentee that self is always available when the network manager received data?")
print("Nope, you can't. Network manager will be alive, regardless of this particular instance of MyViewController")
print("You should use weak self here, since you are not sure if this instance is still alive for every")
print("future callback of network manager")
}
}
}
class NetworkManager {
static let sharedInstance = NetworkManager()
var receivedData: ((Data) -> ())?
private func process(_ data: Data) {
// process the data...
// ... eventually notify a possible listener.
receivedData?(data)
}
}
无主的缺点:
效率比弱 你可以(好吧,你是被迫的)将实例标记为不可变(从Swift 5.0开始就不再这样了)。 向代码的读者表明:这个实例与X有关系,没有它就不能生存,但是如果X消失了,我也就消失了。
弱者的缺点:
比无主更安全(因为它不会崩溃)。 可以创建与X的双向关系,但两者都可以没有对方。
如果你不确定,就用weak。等等,我的意思是在StackOverflow上问问你在这种情况下应该怎么做!在不应该使用weak的情况下一直使用weak只会让您和代码的读者感到困惑。
无主引用是一种弱引用,用于两个对象之间存在同一生命周期关系的情况下,这时一个对象应该只属于另一个对象。它是一种在对象与其属性之一之间创建不可变绑定的方法。
In the example given in the intermediate swift WWDC video, a person owns a credit card, and a credit card can only have one holder. On the credit card, the person should not be an optional property, because you don't want to have a credit card floating around with only one owner. You could break this cycle by making the holder property on the credit a weak reference, but that also requires you to make it optional as well as variable (as opposed to constant). The unowned reference in this case means that although CreditCard does not have an owning stake in a Person, its life depends on it.
class Person {
var card: CreditCard?
}
class CreditCard {
unowned let holder: Person
init (holder: Person) {
self.holder = holder
}
}
link摘录
结论很少
To determine if you even need to worry about strong, weak, or unowned, ask, “Am I dealing with reference types”. If you’re working with Structs or Enums, ARC isn’t managing the memory for those Types and you don’t even need to worry about specifying weak or unowned for those constants or variables. Strong references are fine in hierarchical relationships where the parent references the child, but not vice-versa. In fact, strong references are the most appropraite kind of reference most of the time. When two instances are optionally related to one another, make sure that one of those instances holds a weak reference to the other. When two instances are related in such a way that one of the instances can’t exist without the other, the instance with the mandatory dependency needs to hold an unowned reference to the other instance.
Both weak and unowned references will not impact the reference count of the object. But weak reference will always be optional i.e. it can be nil, whereas unowned references can never be nil so they will never be optional. When using an optional reference you will always have to handle the possibility of the object being nil. In case of an unowned reference you will have to ensure that the object is never nil. Using an unowned reference to a nil object will be similar to forcefully unwrapping an optional that is nil.
也就是说,在确定对象的生命周期大于引用的生命周期时,使用无主引用是安全的。如果不是这样,最好使用弱引用。
As for the third part of the question, I don’t think unowned reference is similar to a dangling pointer. When we talk about reference count, we usually refer to strong reference count of the object. Similarly swift maintains unowned reference count and weak reference counts for the object (weak reference points to something called a "side table" rather than the object itself ). When the strong reference count reaches zero, the object gets deinitialised, but it cannot be deallocated if the unowned reference count is more than zero.
悬空指针指向一个已经被释放的内存位置。但是在swift中,由于内存只有在对象有一个无主引用时才能被释放,所以它不会导致悬空指针。
有很多文章更详细地讨论了swift内存管理。这里有一个。
如果self可以在闭包中为nil,请使用[weak self]。
如果self在闭包中永远不会为nil,请使用[无主的self]。
如果当你使用[un主self]时它崩溃了,那么self在闭包中的某个时候可能是nil,你可能需要使用[weak self]来代替。
查看在闭包中使用strong、weak和u主的示例:
https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html