我对我面临的情况提出了一个小问题。 我有两种方法:
- (void)firstSelector {
[self launchAsyncTask];
... do some work for a long time (10secs) ...
}
- (void)asyncTaskFinished {
... some work after 5secs of async task ...
}
firstSelector
执行launchAsyncTask
这只是一个后台任务,其回调称为asyncTaskFinished
。
假设firstSelector
在启动异步任务后运行一段时间(假设为10秒),并且异步任务运行5秒,是否会出现并发问题?
这是如何在幕后工作的?
在asyncTaskFinished
之后firstSelector
会执行,或firstSelector
会暂停运行asyncTaskFinished
吗?
是否存在运行循环的链接?方法是否已添加到队列中,然后在我调用它们时执行?
我输了:)
谢谢。
答案 0 :(得分:1)
异步任务以异步方式运行,当主循环上运行UI时,异步任务不会在主运行循环上运行。看看Concurrency Programming Guide。
所以在你的情况下,你不确定同步时间将花多长时间。你假设它可能需要10秒,但它并不完全确定。因此,在这种情况下,您需要使用块或在主线程上完成异步任务时找到触发asyncTaskFinished函数的方法。您可以定义一个简单的块回调,然后在异步任务完成时触发该函数。
如果您使用GCD进行异步任务,则变得非常简单。你会这么做的;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self runMyAsyncTask];
// trigger the main completion handler when this completed
dispatch_async(dispatch_get_main_queue(), ^{
[self asyncTaskFinished];
});
});
如果使用NSThread进行并发,则可以使用performSelector:onThread:在异步任务完成时触发完成选择器。对于一个简单的例子,我将向您展示实现一个回调处理程序。您可以创建这样的函数来触发异步任务,
-(void)launchAsyncTaskWithCompletionHandler:(void(^)(void))completionHandler{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self runMyAsyncTask];
// trigger the main completion handler when this completed
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler();
});
});
}
调用它相对简单;
[self launchAsyncTaskWithCompletionHandler:^{
[self asyncTaskFinished];
}];
这很容易理解,使您的代码更清晰。希望这会对你有所帮助。
答案 1 :(得分:0)
线程的运行循环以顺序(非并发)方式从其输入源执行任务。因此,只要在同一个运行循环中执行firstSelector
和asyncTaskFinished
,您就不必担心。这将取决于回调语义。您可能需要使用performSelector:onThread:withObject:waitUntilDone:
之类的东西来确保在正确的线程中执行异步回调函数。