这基本上是我正在做的同步运行异步方法:
这实际上在调用一次时起作用,但是当多次调用时,它最终将保持在while循环内并且永远不会发出信号。有关如何设置计时器以在一段时间后最终超时的任何想法?
__block SomeClass *result = nil;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0UL);
dispatch_async(queue, ^{
[[SomeManager sharedInstance] someMethodWithCallback:^(id responseObject, NSError *error) {
if (!error) {
result = (SomeClass *)ResponseObject;
}
dispatch_semaphore_signal(semaphore);
}];
});
// wait with a time limit
while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW)) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0]];
}
dispatch_release(semaphore);
由于
答案 0 :(得分:1)
这看起来有点像GCD虐待我。 ;)您是否正在运行运行循环,因为这是在主线程上执行的?为什么不直接使用完成处理程序中的dispatch_async()来调用主线程上的处理程序?例如:
- (void)handleDataReady: (id) results error: (NSError *) error {
// update your app
}
- (void)performAsyncUpdate {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0UL);
dispatch_async(queue, ^{
[[SomeManager sharedInstance] someMethodWithCallback:^(id responseObject, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self handleDataReady:responseObject error:error];
}];
});
}
答案 1 :(得分:1)
如果你真的想让它同步,即在操作完成之前阻塞调用线程,那么使用以下模式(当然你想避免阻塞线程,如果可能的话)
NSCondition *waitCondtion = [NSCondition new];
__block BOOL completed = NO;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0UL);
dispatch_async(queue, ^{
[[SomeManager sharedInstance] someMethodWithCallback:^(id responseObject, NSError *error) {
if (!error) {
result = (SomeClass *)ResponseObject;
}
[waitCondtion lock];
completed = YES;
[waitCondition signal];
[waitCondition unlock];
}];
});
[waitCondtion lock];
if (!completed)
[waitCondtion wait];
[waitCondition unlock];
你也可以使用“waitUntilDate:”来延迟一段时间后的等待。
但是,只有“someMethodWithCallback不会在被阻塞的同一个线程上调用其回调块时,此模式才有效。我复制了您的代码,因为实现”someMethodWithCallback“的方式并不明显。正在使用异步模式,那么它必须异步执行某些操作,因此为什么要在dispatch_async中调用它?它会在什么线程上调用它的回调块?
答案 2 :(得分:0)
你应该用完成处理程序完成时处理结果所需的任何代码“填充”完成处理程序(并完全删除该运行循环)。
为了“中止”异步操作,您应该提供发送异步结果提供程序的cancel
消息。
在您的情况下,由于您有一个单身人士,cancel
消息必须像这样发送:
[[SomeManager sharedInstance] cancel];
当操作收到cancel
消息时,它应该尽快中止其任务并使用适当的NSError
对象调用完成处理程序,指示它已被取消。
注意,取消消息可能是异步 - 这意味着,当它返回时,接收方仍然可以执行任务。
您可以通过设置定时器来实现“超时”,定时器会将取消消息发送给操作,除非在操作完成时它已失效。