考虑一下当用户单击按钮时运行的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()是否意味着像上面所示的那样在线程中操作?
我相信这是个简单的问题,但我确实需要一些最佳实践指导。
谢谢!
发布于 2015-03-20 14:34:32
当您在块中引用self时,会存储一个强引用,以便在执行引用之前保持该引用。最佳实践是创建一个弱的自我版本,以避免保留周期。您可以实现这一点,在块外创建弱版本,如目标C中的那样:
__weak typeof(self) weakSelf = self;在Swift中:
var myBlock = {
[weak self] in
//some work with self
}并在块中访问weakSelf而不是self。
您可以在下一个链接中学到更多。
后台线程将继续运行,如果需要成为可取消的任务,则可以实现NSOperations。如果可以在块内展开可选选项,则可以更新UI。
关于beginBackgroundTaskWithExpirationHandler,它被用来标记你将要开始的一项长任务的开始,并获得额外的时间来完成它(并在它完成时通知),以防应用程序在后台运行,但是如果它不能在这段时间内执行,应用程序将被终止。如果需要,您可以使用它,但它不能保证有时间完成任务。
https://stackoverflow.com/questions/29168825
复制相似问题