ios - Swift 闭包 [weak self] 和异步任务

标签 ios swift asynchronous closures

想象一种情况,当您想要从服务器异步加载一些文本并将结果显示在ViewController的 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 上的一些问答并浏览了很多不使用 [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. (Shall we always use [unowned self] inside closure in Swift)

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

或:

But to be clear, it would still be best to use a strong reference in this circumstance. (Swift ARC and blocks)

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

最佳答案

这里没有强引用循环(retain cycle)。如果您使用对 self 的强引用,它会在调度 block 运行时立即解析。如果需要,理论上您可以在此处使用强引用。

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

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

关于ios - Swift 闭包 [weak self] 和异步任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30920576/

相关文章:

ios - UISplitViewController 的详情 View 推送错误

ios - 如何更改 UIImagePicker 中的条形颜色?

ios - 如何过滤数组以更新 TableView ?

iOS 10,QLPreview ViewController 不显示文件

python - 每当我尝试在 VPS 上使用我的 Discord 机器人登录时获取 "SSL: Certificate_verify_failed"

c# - 异步/等待返回调用链如何工作?

ios - 使用 libgdx (roboVM) 创建 iOS 库或框架

ios - APNS错误响应报文中不同状态码的含义

ios - interactivePopGestureRecognizer 弹出到根而不是 1 个顶部 Controller

javascript - 异步功能控制台日志记录乱序