微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决我们应该总是在 Swift 的闭包中使用 [unowned self]

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

示例:发出异步网络请求

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

何时使用uNowned selfweak self

您真正想要使用的唯一时间[uNowned self]或者[weak self]是您将创建一个强大的参考循环的时候。强引用循环是指存在一个所有权循环,其中对象最终相互拥有(可能通过第三方),因此它们永远不会被释放,因为它们都确保彼此保持不变。

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

特别是在视频的例子中

幻灯片上的示例中,通过成员变量TempNotifier拥有闭包。onChange如果他们没有声明selfasuNowned,闭包也会自己self创建一个强引用循环。

uNowned和之间的区别weak

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

解决方法

在 WWDC 2014 session 403 Intermediate
Swift
and
transcript中,有以下幻灯片

在此处输入图像描述

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

Swift Weather 应用程序的 ViewController.swift 的第 64
,我不使用[unowned self]. 但我通过使用一些@IBOutletsself.temperature和来更新 UI
self.loadingIndicator。可能没问题,因为@IBOutlet我定义的所有 s 都是weak.
但是为了安全,我们应该总是使用[unowned self]?

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。