使用callback =并发执行选择器?

时间:2012-12-03 10:12:47

标签: iphone ios cocoa methods concurrency

我对我面临的情况提出了一个小问题。 我有两种方法:

- (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吗?

是否存在运行循环的链接?方法是否已添加到队列中,然后在我调用它们时执行?

我输了:)

谢谢。

2 个答案:

答案 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)

线程的运行循环以顺序(非并发)方式从其输入源执行任务。因此,只要在同一个运行循环中执行firstSelectorasyncTaskFinished,您就不必担心。这将取决于回调语义。您可能需要使用performSelector:onThread:withObject:waitUntilDone:之类的东西来确保在正确的线程中执行异步回调函数。