【问题标题】:What is the difference between self and unowned self in Swift?Swift 中的 self 和 unowned self 有什么区别?
【发布时间】:2015-04-14 19:27:23
【问题描述】:

我想知道下面两个表达式有什么区别?

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

【问题讨论】:

  • 您应该阅读“Swift 编程语言”中的“解决闭包的强引用循环”一章。它解释了这是做什么以及为什么这样做。
  • unowned 表示仅对self引用,因此您阻止不会创建强保留周期。
  • @holex no, weak 表示它是对self 的弱引用。 unowned 表示它是对 self 的无主引用。它们并不相同,尽管它们都用于避免保留循环。
  • @AirspeedVelocity,实际上你是完全正确的,它在技术上不是一个 weak 参考。
  • @AirspeedVelocity weakunowned 有什么区别?

标签: objective-c iphone swift


【解决方案1】:

Swift 内存管理是通过引用计数来执行的。您可以在official Swift docs 中阅读有关引用计数及其含义的精彩摘要。

然而,总而言之——引用计数内存管理的问题是引用循环的风险——对象 A 持有对对象 B 的引用,而对象 B 持有对对象 A 的引用。即使没有人使用其中任何一个对象 A 或 B 不再存在,它们使彼此保持活动状态,防止内存被释放,它们的 deinit 方法被调用等等。

在 Swift 中有两种引用循环的解决方案——弱引用和无主引用。

弱引用不计入对象的引用计数。因此,如果对象 B 只有对对象 A 的弱引用,那么当所有其他强引用都被删除时,对象 A 就会被销毁。显然,风险在于对象 B 可能会尝试使用对象 A。这就是为什么在 Swift 中弱引用是可选的——你必须解开它们(返回强引用而不是弱引用)以检查引用的对象是否仍然存在在那里。

无主引用的相似之处在于它们不会导致对象被保留。然而,与弱引用不同,它们不是可选的,不需要先检查。相反,来自文档:

如果您尝试在它的实例之后访问无主引用 引用被释放,您将触发运行时错误。利用 仅当您确定该引用将 总是引用一个实例。

另请注意,如果您尝试这样做,Swift 会保证您的应用程序会崩溃 在它引用的实例之后访问一个无主引用 解除分配。您将永远不会在此遇到意外的行为 情况。您的应用程序将始终可靠地崩溃,尽管您应该, 当然,阻止它这样做。

这意味着你应该只在你知道的情况下使用它们,根据你的程序逻辑,无主对象永远不会在持有无主引用的对象之前被销毁。 Swift 文档中的示例是 CustomerCreditCard - 众所周知,没有客户,信用卡永远不会存在,因此它可以拥有对其客户的无主引用,而不会冒客户在信用时被销毁的风险卡仍在使用中。

除了更易于使用(无需解包)之外,无主引用的总体开销较低,因此存在一定的风险/回报回报。即使弱引用对对象的引用计数没有贡献,它们仍然需要某种程度的跟踪,无主引用较少。

【讨论】:

  • 很好的答案。所以使用[weak self]而不是[unowned self]可能会更好?
  • weak 始终是更安全的选择。 unowned 是一种性能优化/便利,当您确定您的程序的结构不可能无效时。把它想象成数组下标——当你访问myArray[5]时,你需要确保有这样一个元素,有时你的代码是这样写的,总是会有,但如果不是,你的应用程序可能会崩溃。
猜你喜欢
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
  • 2014-08-02
  • 2015-10-04
  • 2020-06-16
  • 2015-03-07
  • 1970-01-01
相关资源
最近更新 更多