我想知道以下两个表达式之间有什么区别?
foregroundNotification = NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationWillEnterForegroundNotification, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: {
(notification:NSNotification!) -> Void in
// do something
})
和(与unowned self
):
foregroundNotification = NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationWillEnterForegroundNotification, object: nil, queue: NSOperationQueue.mainQueue(), usingBlock: {
[unowned self] (notification:NSNotification!) -> Void in
// do something
})
答案 0 :(得分:8)
通过引用计数执行Swift内存管理。您可以在official Swift docs中阅读有关引用计数及其含义的完整摘要。
然而,总结一下 - 引用计数内存管理的问题是引用周期的风险 - 对象A保存对对象B的引用,对象B保存对对象A的引用。即使没有人使用任何一个对象A或B,它们彼此保持活着,防止释放内存,调用它们的deinit
方法等。
Swift中引用循环有两种解决方案 - 弱引用和无主引用。
弱引用不计入对象的引用计数。因此,如果对象B只有对象A的弱引用,那么当删除所有其他强引用时,对象A将被销毁。显然风险在于对象B可能会尝试使用对象A.这就是为什么在Swift中弱引用是选项 - 你必须打开它们(它返回一个强引用而不是弱引用)来检查引用的对象是否仍然存在那里。
无主引用类似,因为它们不会导致保留对象。但是,与弱引用不同,它们不是可选项,不需要先进行检查。相反,来自文档:
如果您尝试在实例之后访问无主引用 引用被释放,您将触发运行时错误。使用 只有当您确定引用时才会使用无主引用 总是指一个实例。
另请注意,如果您尝试,Swift会保证您的应用会崩溃 在引用的实例之后访问无主引用 释放。你永远不会遇到意想不到的行为 情况。您的应用程序将始终可靠地崩溃,尽管您应该, 当然,防止它这样做。
这意味着您应该只在您根据程序的逻辑知道在拥有无主引用的对象之前无法销毁无主对象的情况下使用它们。 Swift文档中的示例是Customer
和CreditCard
- 已知信用卡在没有客户的情况下永远不会存在,因此它可以拥有对其客户的无主参考而不存在该客户的风险在信用卡仍在使用时被销毁。
除了更易于使用(无需解包)之外,无主引用具有较低的总体开销,因此存在一些风险/回报支付。尽管弱引用不会对对象的引用计数产生影响,但它们仍然需要一定程度的跟踪,无限引用也不需要。