在我的 iOS 应用程序中,我想在更新 UI 之前等待条件变为真。
我正在这样做:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
while (!condition) NSLog("waiting for the condition");
dispatch_sync(dispatch_get_main_queue, ^{
//update the UI here
});
});
上面的代码工作得很好,但我想问一下使用while循环来做等待工作是否好,是否有更好的方法。
谢谢!
- -更新
条件实际上是 4 个 BOOL 变量的组合。每个变量都与来自服务器的内容请求相关联。我正在使用 AFNetworking 框架。在 4 个请求的每一个的完成 block 中,我将关联的 BOOL 变量设置为 YES。
所以,实际的while循环是这样的:
while (!([MyRequest request1].isFinished && [MyRequest request2].isFinished && [MyRequest request3].isFinished && [MyRequest request4].isFinished)) NSLog("waiting for the condition");
最佳答案
在修改后的问题中,听起来你有四个 AFNetworking
您想要依赖的操作。那要容易得多。您可能只是添加一个新操作,并使其依赖于其他四个操作:
NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// update UI
}];
}];
[operation addDependency:requestOneOperation];
[operation addDependency:requestTwoOperation];
[operation addDependency:requestThreeOperation];
[operation addDependency:requestFourOperation];
[queue addOperation:operation];
addDependency
机制本质上是 isFinished
的 KVO为您提供的其他四个操作中的每一个。这是使用 NSOperation
的乐趣之一。 AFNetworking 等基于框架的框架。这种依赖真的很容易做到。原答案:
如果你必须这样做,你可能会使用一个信号量,例如,你会创建一个信号量:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
你会让你的异步 block 等待:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
dispatch_semaphore_wait(semaphore);
dispatch_sync(dispatch_get_main_queue, ^{
//update the UI here
});
});
当条件满足时,原本设置此条件标志的代码将改为:
dispatch_semaphore_signal(semaphore);
话虽如此,除非绝对必要,否则我宁愿不要看到像这样阻塞的队列(甚至是并发的全局队列)。如果其他代码可以发出信号量信号,我不确定它为什么不能自己启动 UI 更新。如果我确实使用了这种信号量技术,至少我会让这个等待过程发生在我自己创建的队列上,而不是全局队列上。
您可以在许多情况下使用并且我可能更喜欢的另一种方法是使用 key value observing :
例如,我可以观察到它们的变化
someProperty
名为 obj
的对象的属性像这样:[obj addObserver:self forKeyPath:@"someProperty" options:NSKeyValueObservingOptionNew context:NULL];
然后我会执行
observeValueForKeyPath
:- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"someProperty"])
{
NSLog(@"update UI here");
}
}
每当
someProperty
我的 obj
的属性(property)对象已更新,我的 observeValueForKeyPath
方法将被调用。仅供引用,我还要确保在此对象被释放之前,我会删除
obj
的观察者:[obj removeObserver:self forKeyPath:@"someProperty"];
显然,这假设
someProperty
是 Key Value Coding Compliant .但如果是这样,这是一项很棒的技术。
关于ios - GCD : asynchronously wait for condition,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19194009/