【问题标题】:Swift closures [weak self] and async tasksSwift 闭包 [weak self] 和异步任务
【发布时间】:2015-09-04 09:35:45
【问题描述】:

想象一种情况,当您想要异步从服务器加载一些文本并将结果显示在 ViewController's UITextField

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {

    //... some long running async operation

    if let textResponse = responseFromServer {
        dispatch_async(dispatch_get_main_queue(), { [weak self] () in
            self?.textField.text = textResponse
        })
    }
})

A.) 我需要在用于异步调用的闭包中使用 [weak self] 吗?

我认为我需要这样做,但在阅读了 StackOverflow 上的一些 Q/A 并浏览了很多不使用 [weak self] 进行异步任务 + 闭包的开源应用程序之后,我不确定。

即:

你真正想要使用 [unowned self] 或 [weak self] 是您创建强参考循环的时候。 (Shall we always use [unowned self] inside closure in Swift)

在我的例子中没有强引用循环。

或:

但要明确一点,最好还是使用强引用 这种情况。 (Swift ARC and blocks)

B.) 假设使用强参考很好。 当用户在异步加载过程中导航到不同的页面时,ViewController 会发生什么?它会在异步任务完成之前将不可见的 ViewController 保留在应用内存中吗?

【问题讨论】:

    标签: ios swift asynchronous closures


    【解决方案1】:

    这里没有强引用循环(retain cycle)。如果您使用对self 的强引用,则它会在调度块运行后立即解决。如果需要的话,理论上你可以在这里使用强引用。

    话虽如此,我建议在这种情况下使用弱引用。在耗时过程的持续时间内保持强引用是没有意义的,仅仅是为了更新已经被关闭的视图的文本字段。如果您正在更新其他模型对象等,也许您可​​能需要保留强引用,但在这种情况下您不需要这样做。作为一般原则,应该尽快释放内存。

    更好的是,我还会查看“长时间运行的异步操作”并决定我是否真的希望它在视图控制器被关闭后继续运行。如果不是,我也倾向于取消请求,然后让deinit 取消请求。而且,在这种情况下,您肯定希望使用弱引用(否则在长时间运行的异步操作完成之前不会调用 deinit)。

    【讨论】:

      猜你喜欢
      • 2016-05-02
      • 1970-01-01
      • 1970-01-01
      • 2015-07-02
      • 1970-01-01
      • 2019-12-03
      • 2017-07-22
      • 2018-10-11
      • 1970-01-01
      相关资源
      最近更新 更多