我们总是在Swift中使用[unowned self]内部封闭 [英] Shall we always use [unowned self] inside closure in Swift

查看:111
本文介绍了我们总是在Swift中使用[unowned self]内部封闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在WWDC 2014会议403 。一个强大的参考周期是当存在一个所有权循环,其中对象最终彼此拥有(可能通过第三方),因此它们将永远不会被释放,因为它们都确保彼此坚持。



在闭包的特定情况下,您只需要意识到在其中引用的任何变量都由闭包拥有。只要封闭物周围,这些物体就可以保证在周围。阻止该所有权的唯一方法是执行 [无主自我] [弱自我] 。因此,如果一个类拥有一个闭包,并且该闭包捕获了对该类的强引用,那么闭包和类之间就有一个强大的引用循环。这还包括如果该类拥有拥有该闭包的东西。



特别是在视频的示例中



在幻灯片上的示例中, TempNotifier 通过 onChange 成员变量拥有闭包。如果他们没有将 self 声明为无主,那么关闭也将​​拥有 self 创建一个强大的参考周期。



无主



无主被声明为可选,而无主则不是。通过声明它 weak ,您可以处理在某些时候它可能在闭包内部为零的情况。如果您尝试访问恰好为nil的无主变量,则会导致整个程序崩溃。所以只有当你肯定变量总是存在时,才会使用无主,而闭包是在


In WWDC 2014 session 403 Intermediate Swift and transcript, there was the following slide

The speaker said in that case, if we don't use [unowned self] there, it will be a memory leak. Does it mean we should always use [unowned self] inside closure?

On line 64 of ViewController.swift of the Swift Weather app, I don't use [unowned self]. But I update the UI by using some @IBOutlets like self.temperature and self.loadingIndicator. It may be OK because all @IBOutlets I defined are weak. But for safety, should we always use [unowned self]?

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

解决方案

No, there are definitely times where you would not want to use [unowned self]. Sometimes you want the closure to capture self in order to make sure that it is still around by the time the closure is called.

Example: Making an asynchronous network request

If you are making an asynchronous network request you do want the closure to retain self for when the request finishes. That object may have otherwise been deallocated but you still want to be able to handle the request finishing.

When to use unowned self or weak self

The only time where you really want to use [unowned self] or [weak self] is when you would create a strong reference cycle. A strong reference cycle is when there is a loop of ownership where objects end up owning each other (maybe through a third party) and therefore they will never be deallocated because they are both ensuring that each other stick around.

In the specific case of a closure, you just need to realize that any variable that is referenced inside of it, gets "owned" by the closure. As long as the closure is around, those objects are guaranteed to be around. The only way to stop that ownership, is to do the [unowned self] or [weak self]. So if a class owns a closure, and that closure captures a strong reference to that class, then you have a strong reference cycle between the closure and the class. This also includes if the class owns something that owns the closure.

Specifically in the example from the video

In the example on the slide, TempNotifier owns the closure through the onChange member variable. If they did not declare self as unowned, the closure would also own self creating a strong reference cycle.

Difference between unowned and weak

The difference between unowned and weak is that weak is declared as an Optional while unowned is not. By declaring it weak you get to handle the case that it might be nil inside the closure at some point. If you try to access an unowned variable that happens to be nil, it will crash the whole program. So only use unowned when you are positive that variable will always be around while the closure is around

这篇关于我们总是在Swift中使用[unowned self]内部封闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆