iOS GCD 线程处理 - 视图控制器已关闭

iOS GCD Thread Processing - View Controller Dismissed

考虑 ViewController 中的以下代码,当用户单击按钮时 运行s:

var myBlock = {
    [weak self] in
    let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
    dispatch_async(queue) {
        // Some heavy lifting code with final UI Feedback
        let success = true
        if(success) {
            if let strongSelf = self {
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    // Tell user it was successful
                    strongSelf.label1.text = "SUCCESS!"
                });
            }
        }
    });
}

在发生繁重工作的区域,假设有一个过程大约需要 5-10 秒。如果在那段时间用户关闭了这段代码所在的ViewController,后台线程是否继续运行?如果是这样,当成功块 运行s 并尝试访问 UI 线程上的 UI 元素时,会发生什么?

最终,我试图了解在后台排队更新 UI 的进程的最佳实践。此外,如果用户按下主页按钮,此过程必须在后台继续完成。我读到您可以添加:UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler() 是否意味着在线程内操作,如上所示?

我确定这是一个有点菜鸟的问题,但我真的可以在这里使用一些最佳实践指导。

谢谢!

当您在块中引用 self 时,会存储一个强引用,以便在执行之前保留该引用。最佳做法是创建一个弱自我版本以避免保留周期。您可以像在 Objective C:

中那样在块外创建弱版本来实现此目的
__weak typeof(self) weakSelf = self;

在Swift中:

var myBlock = {
[weak self] in
//some work with self
}

并在块中访问 weakSelf 而不是 self。

接下来link可以多学一点。

后台线程会继续运行,如果需要是可取消的任务,可以实现NSOperations。如果你可以在块内打开可选的,你可以更新 UI.

关于beginBackgroundTaskWithExpirationHandler,它用于标记您即将开始的长任务的开始,并获得额外的时间来完成它(并在完成时通知),以防App后台运行,但如果它届时无法执行该应用程序将被终止。如果您需要,您可以使用它,但它不能确保有时间完成您的任务。