Swift闭包[弱自我]和异步任务

时间:2015-06-18 16:12:15

标签: ios swift asynchronous closures

想象一下这种情况,当你想要异步从服务器加载一些文本并在 ViewController's UITextField中显示结果时。< / p>

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。)我是否需要在用于异步调用的闭包中使用[弱自我]?

我认为我需要,但我不确定在我在StackOverflow上阅读了一些Q / A并经历了一些不使用[弱自我]进行异步任务+闭包的开源应用程序。

即:

  

你真正想要使用[无主自我]或[弱]的唯一时间   自我]是你创建一个强大的参考周期。   (Shall we always use [unowned self] inside closure in Swift

在我的案例中没有强大的参考周期。

或:

  

但要明确的是,最好使用强大的参考资料   这种情况。 (Swift ARC and blocks

B。)让我们说强有力的参考是好的。 当用户在异步加载过程中导航到不同的页面时,ViewController会发生什么?在异步任务完成之前,是否会将不可见的ViewController保留在应用程序内存中?

1 个答案:

答案 0 :(得分:13)

这里没有强大的参考周期(保留周期)。如果您对self使用强引用,则在调度块运行后立即解析。理论上,如果需要,你可以在这里使用强引用。

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

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