“Like a weak reference, an unowned reference does not keep a strong hold on the instance it refers to. Unlike a weak reference, however, an unowned reference is used when the other instance has the same lifetime or a longer lifetime. You indicate an unowned reference by placing the unowned keyword before a property or variable declaration.”
摘录来自: Apple Inc. “The Swift Programming Language (Swift 3.1)”。 iBooks.
Swift中经常使用unowned和weak来修饰逃逸闭包中的变量,以避免Strong Reference Cycles;知道这个特性后,心想妈妈再也不怕我写循环引用了!!!
于是有了如下代码:
private lazy var pendingBadge: JSBadgeView = { [unowned self] in
return JSBadgeView.init(parentView: self.pendingButton, alignment: .topRight)
}()
func updateOrderCount() -> Void {
HTTPSManager.shared().getDataWithActionStr(API_GetOrderCount, params: ["state": "0"], isShowHUD: false, success: { [unowned self] (object: Any?) in
let responseObject = object as? NSDictionary
let countOption = responseObject?.safelyValue(forKey: "retData") as? Int
if let count = countOption, count > 0 {
self.audtingBadge.badgeText = String(count)
} else {
self.audtingBadge.badgeText = nil
}
}, failure: nil)
}
如果你感觉上边的Swift代码有些瑕疵,好吧,有些是从Objective-C桥接过来的☺。
上边代码看上去没什么问题,可是发过生产才意识到,unowned有问题!!!!果然打开Bugly一看,已经有了三五个issue。
苹果给的提示:
“Use an unowned reference only when you are sure that the reference always refers to an instance that has not been deallocated.
If you try to access the value of an unowned reference after that instance has been deallocated, you’ll get a runtime error.”
摘录来自: Apple Inc. “The Swift Programming Language (Swift 3.1)”。 iBooks.
unowned修饰的变量不能保证其一定有值,它和weak的区别是不会自动nil化;如果引用的对象已经被释放掉了,再向其发送消息就极可能crash。
另外,不管是OC还是Swift,很多人看到闭包就用weak修饰引用的变量,其实在保证不会造成Strong Reference Cycles的情况下,保持对象的强引用还是很有必要的。