有没有办法在代码中“等待......” - 就像一个空循环?

时间:2014-02-14 09:07:03

标签: ios objective-c semaphore promise nsnotificationcenter

考虑以下代码:

[self otherStuff];
// "wait here..." until something finishes
while(!self.someFlag){}
[self moreStuff];

请注意,这一切都发生在相同的线程 - 我们不想转到另一个线程。

otherStuff可以做一些事情,比如连接到云,从用户那里获取输入等等,这样会花费很多时间并且可以遵循许多可能的路径。

otherStuff将self.someFlag设置为true,当otherStuff最终完成时。

这完全有效,并且完全没有问题 - 除了用空循环烧毁处理器是蹩脚的!!

很简单,有没有办法说出像......

halt here, until (some message, interrupt, flag, boolean, whatever?)

而不仅仅是(!self.someFlag){}

(注意另一种方法是“链接”程序...所以在“otherStuff”的结尾,你和所有其他程序员必须“只知道”你必须接下来调用“moreStuff”,不管其他玩家如何玩,等等。当然,当你必须添加新程序或改变事情的顺序时,这是非常混乱的。)干杯!!

顺便说一下,如果你想要不同的线程,下面已经有两个很好的答案。

2 个答案:

答案 0 :(得分:4)

这是一个使用信号量的解决方案,小心不要引入死锁 - 你需要某种方式告诉你的应用程序已完成的事情,你可以使用你建议的NSNotificationCentre但使用块来做到这一点很多更容易。

[self someOtherStuffWithCompletion:nil];

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

[self someOtherStuffWithCompletion:^{
  dispatch_semaphore_signal(semaphore);
}];

NSLog(@"waiting");
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"finished");

[self someOtherStuffWithCompletion:nil];

答案 1 :(得分:1)

我建议使用NSOperationQueue并等待所有任务,直到它们在特定点完成。这样的事情:

self.queue = [[NSOperationQueue alloc] init];

// Ensure a single thread
self.queue.maxConcurrentOperationCount = 1;

// Add the first bunch of methods
[self.queue addOperation:[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(method1) object:nil]];
[self.queue addOperation:[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(method2) object:nil]];
[self.queue addOperation:[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(method3) object:nil]];

// Wait here
[self.queue waitUntilAllOperationsAreFinished];

// Add next methods
[self.queue addOperation:[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(method4) object:nil]];
[self.queue addOperation:[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(method5) object:nil]];

// Wait here
[self.queue waitUntilAllOperationsAreFinished];

HTH