这是 Apple 使用 GCD(Grand Central Dispatch)推荐的最快方式。它也更容易阅读和理解,因为逻辑是线性的,但没有在方法之间拆分。
请注意,它显示了weakSelf“舞蹈”,如果异步可能比它所要求的控制器寿命更长,那么它是必要的,因此它对它进行弱引用,然后检查它是否还活着并保留它以进行更新:
斯威夫特 4 & 3
DispatchQueue.global().async() {
print("Work Dispatched")
// Do heavy or time consuming work
// Then return the work on the main thread and update the UI
// Create weak reference to self so that the block will not prevent it to be deallocated before the block is called.
DispatchQueue.main.async() {
[weak self] in
// Return data and update on the main thread, all UI calls should be on the main thread
// Create strong reference to the weakSelf inside the block so that it´s not released while the block is running
guard let strongSelf = self else {return}
strongSelf.method()
}
}
Objective-C
// To prevent retain cycles call back by weak reference
__weak __typeof(self) weakSelf = self; // New C99 uses __typeof(..)
// Heavy work dispatched to a separate thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"Work Dispatched");
// Do heavy or time consuming work
// Task 1: Read the data from sqlite
// Task 2: Process the data with a flag to stop the process if needed (only if this takes very long and may be cancelled often).
// Create strong reference to the weakSelf inside the block so that it´s not released while the block is running
__typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf method];
// When finished call back on the main thread:
dispatch_async(dispatch_get_main_queue(), ^{
// Return data and update on the main thread
// Task 3: Deliver the data to a 3rd party component (always do this on the main thread, especially UI).
});
}
});
取消进程的方法是包含一个 BOOL 值并将其设置为在不再需要正在完成的工作时从主线程停止。但是,这可能不值得,因为除非进行大量计算,否则用户不会注意到后台工作太多。为了防止保留循环,请使用弱变量,例如:
__weak __typeof(self) weakSelf = self; // Obj-C
[weak self] in
并在块内使用强引用调用weakSelf(以防止调用VC已被释放时崩溃)。您可以使用 UIViewController 之类的确切类型或 __typeof() 函数(在 C99 中您需要使用 __typeof(..) 但以前您可以直接使用 __typeof(..) )来引用实际类型:
Objective-C
__typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf method];
}
斯威夫特 4 & 3
if let weakSelf = self {
weakSelf.method()
}
或者
// If not referring to self in method calls.
self?.method()
注意:使用 GCD 或 Grand Central Dispatch,这是最简单的,Apple 推荐的方式,代码流按逻辑顺序排列。