1

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

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

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

我迷路了 :)

谢谢你。

4

2 回答 2

1

异步任务异步运行,它不在主运行循环上运行,而 UI 在主循环上运行。查看并发编程指南

因此,在您的情况下,您不确定同步时间需要多长时间。您假设它可能需要 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];
    }];

这很容易理解,并使您的代码更加清晰。希望这对您有所帮助。

于 2012-12-03T10:53:44.890 回答
0

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

于 2014-01-25T23:07:58.737 回答