在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()
这是否意味着如上所示在一个线程内运行?
我确信这是一个小问题,但我可以在这里使用一些最佳实践指导。
谢谢!
答案 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;在那段时间内执行应用程序将被终止。如果需要,您可以使用它,但不能确保有时间完成任务。