lak*_*esh 6 multithreading ios
我需要执行异步函数执行,因为它阻塞了主线程,因此UI不可用.
在查看stackoverflow中的问题后,我知道有三种方法可以执行异步功能.
一个例子:
[NSThread detachNewThreadSelector:@selector(showSpinner:) toTarget:self withObject:self.view];
// or
[self performSelectorInBackground:@selector(showSpinner:) withObject:self.view];
// or
NSInvocationOperation *invOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(showSpinner:) object:self.view];
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperation:invOperation];
// or
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[self showSpinner:self.view];
});
});
Run Code Online (Sandbox Code Playgroud)
我的问题是如何performSelectorInBackground和detachNewThreadSelector回返回主线程?你怎么知道他们已经完成了?
几点想法:
您可能希望在" 并发编程指南"中检查"远离线程迁移",这为调度队列和操作队列提供了一个引人注目的参数,这在前面的同一指南中已有讨论.
此外,当您深入研究各种异步操作时,请记住,在后台队列/线程中耗费时间,但始终将UI内容分配回主队列.我只提到这一点,因为你的任务showSpinner听起来很像UI任务,你永远不想在后台队列/线程中做.如果它有一些"昂贵的"非UI相关任务,那么很好,在后台执行,但确保UI内容被调度回主队列.
除此之外,还有其他操作队列的再现,例如块操作:
NSOperationQueue *opQueue = [[NSOperationQueue alloc] init];
[opQueue addOperationWithBlock:^{
// do some slow stuff in the background here
// ok, now do UI stuff in the main queue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self showSpinner:self.view];
}];
}];
Run Code Online (Sandbox Code Playgroud)
这大致相当于GCD(调度队列)再现:
dispatch_queue_t dispatchQueue = dispatch_queue_create("com.ramshad.app", 0);
dispatch_async(dispatchQueue, ^{
// do some slow stuff in the background here
// ok, now do UI stuff in the main queue
dispatch_async(dispatch_get_main_queue(), ^{
[self showSpinner:self.view];
});
});
Run Code Online (Sandbox Code Playgroud)
操作队列和调度队列之间存在许多微妙的优点和缺点(我们不应该在这里讨论它,因为它已经在Stack Overflow上的其他地方讨论了数百次),但是这两者都让你做了比传统的更复杂的异步操作.线程编程.
如果您决定坚持使用线程与操作和/或调度队列(我不一定会推荐),您可能需要查看" 线程编程指南".
要识别执行performSelectorInBackground 结束 detachNewThreadSelector,请在主线程上的线程方法末尾调用一个方法。
ExtrayNSThread提供了一个属性,isFinished它返回一个布尔值,指示接收者是否已完成执行。
例子:
[self performSelectorOnMainThread:@selector(threadMethod)
withObject:nil
waitUntilDone:NO];
Run Code Online (Sandbox Code Playgroud)
或者
[NSThread detachNewThreadSelector:@selector(threadMethod)
toTarget:self
withObject:nil];
-(void)threadMethod{
//here your implementation code
//here call the end notification method.
[self performSelectorOnMainThread:@selector(ThreadExecutionDone)
withObject:nil
waitUntilDone:YES];
}
-(void)ThreadExecutionDone{
//end of the performSelectorInBackground or detachNewThreadSelector.
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6271 次 |
| 最近记录: |