swift - 我们应该总是在 Swift 的闭包中使用 [unowned self] 吗?

标签 swift automatic-ref-counting

在 WWDC 2014 session 403 Intermediate Swifttranscript , 有如下幻灯片

enter image description here

演讲者在那种情况下说,如果我们不在那里使用[unowned self],就会发生内存泄漏。这是否意味着我们应该始终在闭包中使用 [unowned self]

关于 line 64 of ViewController.swift of the Swift Weather app ,我不使用 [unowned self]。但是我通过使用一些 @IBOutlet 来更新 UI,例如 self.temperatureself.loadingIndicator。这可能没问题,因为我定义的所有 @IBOutlet 都是 weak。但是为了安全起见,我们是否应该始终使用 [unowned self]

class TempNotifier {
  var onChange: (Int) -> Void = {_ in }
  var currentTemp = 72
  init() {
    onChange = { [unowned self] temp in
      self.currentTemp = temp
    }
  }
}

最佳答案

不,肯定有很多时候你不想使用[unowned self]。有时您希望闭包捕获 self 以确保在调用闭包时它仍然存在。

示例:发出异步网络请求

如果您正在发出异步网络请求,您确实希望闭包在请求完成时保留self。该对象可能已被释放,但您仍然希望能够处理完成的请求。

何时使用unowned selfweak self

你真正想要使用[unowned self][weak self] 的唯一一次是当你创建一个strong reference cycle 时。 .强引用循环是指存在一个所有权循环,其中对象最终拥有彼此(可能通过第三方),因此它们永远不会被释放,因为它们都确保彼此坚持下去。

在闭包的特定情况下,您只需要意识到在闭包中引用的任何变量都会被闭包“拥有”。只要闭包存在,这些对象就一定存在。停止所有权的唯一方法是执行 [unowned self][weak self]。因此,如果一个类拥有一个闭包,并且该闭包捕获了对该类的强引用,那么您在闭包和类之间就有了一个强引用循环。这还包括类是否拥有拥有闭包的东西。

特别是视频中的例子

在幻灯片的示例中,TempNotifier 通过 onChange 成员变量拥有闭包。如果他们没有将 self 声明为 unowned,则闭包也将拥有 self,从而形成一个强引用循环。

unownedweak 的区别

unownedweak 之间的区别在于 weak 被声明为可选,而 unowned 不是。通过将它声明为 weak,您可以处理在某些时候它在闭包内可能为 nil 的情况。如果你试图访问一个恰好为 nil 的 unowned 变量,它会导致整个程序崩溃。因此,只有当您确定变量在闭包存在时始终存在时才使用 unowned

关于swift - 我们应该总是在 Swift 的闭包中使用 [unowned self] 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24320347/

相关文章:

objective-c - 寻找在运行时崩溃的有效 Objective-C ARC 代码示例

objective-c - ObjC 弧 : does a weak property's setter method run when the object is set to nil by ARC?

objective-c - 在另一个 NSView(特别是 WebView)上绘制一个透明覆盖层

iphone - 我不应该为 UIViewController 属性使用 (nonatomic, weak) 吗?

ios - 自动引用计数需要 CGPathRelease 吗?

iOS : ARC, 未释放内存

Swift 中的类变量

swift - 使用 Core Plot 和 Swift 的多个散点图

ios - 获取 UIPageViewController 当前索引的可靠方法

ios - 为什么不将工作从 NSData 转换为 String? swift