iOS GCD线程处理 - 视图控制器被解雇

时间:2015-03-20 14:24:32

标签: ios multithreading swift background-process

在ViewController中考虑以下代码,该代码在用户单击按钮时运行:

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,后台线程是否继续运行?如果是这样,当成功块运行并尝试访问UI线程上的UI元素时,会发生什么?

最终,我试图了解在后台排队进程的最佳做法,以便在可能的情况下更新UI。此外,如果用户按下主页按钮,则此过程必须在后台继续完成。我已经读过你可以添加:UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler()这是否意味着如上所示在一个线程内运行?

我确信这是一个小问题,但我可以在这里使用一些最佳实践指导。

谢谢!

1 个答案:

答案 0 :(得分:1)

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

中实现此功能,在块外部创建弱版本
__weak typeof(self) weakSelf = self;

在斯威夫特:

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

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

您可以在下一个link中了解更多信息。

后台线程将继续运行,如果您需要是可取消的任务,则可以实施NSOperations。如果您可以在块中打开可选项,则可以更新UI。

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