在SWIFT中,我们是否应该始终使用[自己不拥有的]内部封闭

在SWIFT中,我们是否应该始终使用[自己不拥有的]内部封闭

在WWDC 2014会议上403中间SWIFT成绩单,有下面的幻灯片

enter image description here

演讲者说,如果我们不用[unowned self]在那里,这将是一个内存泄漏。这是否意味着我们应该一直使用[unowned self]内部关闭?

在……上面ViewController.Swift天气应用程序的第64行,我不使用[unowned self]..但是我使用一些@IBOutlet就像self.temperatureself.loadingIndicator..可能没问题,因为@IBOutlets我定义的是weak..但是为了安全,我们是不是应该一直用[unowned self]?

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


鸿蒙传说
浏览 632回答 3
3回答

翻阅古今

不,肯定有你不想用的时候[unowned self]..有时,您希望闭包捕获Self,以确保在调用闭包时它仍然存在。示例:发出异步网络请求如果您正在发出异步网络请求,则做希望保留闭包self当请求完成时。否则,该对象可能已被解除分配,但您仍然希望能够处理请求完成。何时使用unowned self或weak self你唯一想用的时间[unowned self]或[weak self]是当您创建一个强参考周期..一个强大的引用周期是当存在一个所有权循环时,对象最终相互拥有(可能通过第三方),因此它们永远不会被释放,因为它们都确保了彼此的存在。在闭包的特定情况下,您只需要意识到在其中引用的任何变量都会被闭包“拥有”。只要闭包在附近,这些对象就一定会出现。阻止这种所有权的唯一方法是[unowned self]或[weak self]..因此,如果一个类拥有一个闭包,并且该闭包捕获了对该类的强引用,那么在闭包和类之间有一个很强的引用周期。这还包括类是否拥有闭包的东西。特别是在视频的例子中在幻灯片的例子中,TempNotifier通过onChange成员变量如果他们不宣布self如unowned,关闭也将拥有self创建一个强大的参考周期。差异unowned和weak.之间的区别unowned和weak那是weak声明为可选时间。unowned不是。宣布weak你需要处理的情况是,它可能是零内关闭在某个时间点。如果您试图访问unowned变量碰巧为零,它将使整个程序崩溃。所以只能用unowned当您是正数时,当闭包出现时,该变量将始终存在。

交互式爱情

我想我应该为视图控制器添加一些具体的例子。许多解释,不仅仅是Stack溢出的解释,真的很好,但我更好地处理了现实世界的例子(@drewag在这方面有了一个良好的开端):如果您有一个闭包来处理来自网络请求的响应,请使用weak因为他们活得很久。视图控制器可以在请求完成之前关闭self在调用闭包时不再指向有效对象。如果有处理按钮上的事件的闭包。这可能是unowned因为一旦视图控制器消失,按钮和它可能引用的任何其他项就会从self同时离开。封闭区也会同时消失。class MyViewController: UIViewController {       @IBOutlet weak var myButton: UIButton!       let networkManager = NetworkManager()       let buttonPressClosure: () -> Void // closure must be held in this class.        override func viewDidLoad() {           // use unowned here          buttonPressClosure = { [unowned self] in               self.changeDisplayViewMode() // won't happen after vc closes.            }           // use weak here          networkManager.fetch(query: query) { [weak self] (results, error) in               self?.updateUI() // could be called any time after vc closes          }       }       @IBAction func buttonPress(self: Any) {          buttonPressClosure()       }       // rest of class below. }
打开App,查看更多内容
随时随地看视频慕课网APP