Raf*_*ael 17 user-interface multithreading objective-c freeze ios
我需要做以下任务:
1)从sqlite数据库中读取一些数据
2)处理数据
3)用处理过的数据生成一些图表
如果我有一个用户在应用程序中输入了许多数据,那么有一天这个分析可能会变慢并冻结UI.
那么,处理它的正确方法是什么,允许用户与UI交互,可以选择取消操作还是退出屏幕?
我需要为我的所有任务创建简单的线程,并使用取消事件或标志来停止每个任务?或者还有另一种方法吗?
例如:
任务1:在带有标志的线程中从sqlite读取数据,以便在需要时停止进程.
任务2:使用标志处理带有标志的线程中的数据,以便在需要时停止进程.
任务3:将数据传递给第三方组件.此时,它可以取消正在其他组件上运行的操作吗?
我是在思考正确的方法,还是可以改进某些方面?
Han*_*son 26
这是Apple与GCD(Grand Central Dispatch)推荐和最快的方式.它也更容易阅读和理解,因为逻辑是线性的,但不是在方法之间分开.
请注意,它显示了weakSelf"dance",这是必要的,如果async可能比它所调用的控制器寿命更长,因此它对它进行弱引用,然后检查它是否存活并保留它以进行更新:
斯威夫特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()
}
}
Run Code Online (Sandbox Code Playgroud)
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).
});
}
});
Run Code Online (Sandbox Code Playgroud)
取消该过程的方法是包括BOOL值,并将其设置为从主线程停止,如果不再需要完成工作.但是,它可能不值得,因为除非计算量很大,否则用户不会注意到背景工作.要防止保留周期,请使用弱变量,例如:
__weak __typeof(self) weakSelf = self; // Obj-C
[weak self] in
Run Code Online (Sandbox Code Playgroud)
并在块内强引用调用weakSelf(以防止在释放调用VC时崩溃).你可以使用像UIViewController或__typeof()函数这样的确切类型(在C99中你需要使用__typeof(..),但之前你可以直接使用__typeof(..)来引用实际类型:
Objective-C的
__typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf method];
}
Run Code Online (Sandbox Code Playgroud)
斯威夫特4&3
if let weakSelf = self {
weakSelf.method()
}
Run Code Online (Sandbox Code Playgroud)
要么
// If not referring to self in method calls.
self?.method()
Run Code Online (Sandbox Code Playgroud)
注意:使用GCD或Grand Central Dispatch,这是最简单的,Apple推荐的方式,代码流按逻辑顺序排列.
归档时间: |
|
查看次数: |
10710 次 |
最近记录: |