【问题标题】:Is there any way to "wait here..." in code - just like an empty loop?有没有办法在代码中“在这里等待......” - 就像一个空循环一样?
【发布时间】:2014-03-13 13:23:45
【问题描述】:

考虑这段代码:

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

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

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

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

这很完美,完全没有问题——除了像这样用空循环烧毁处理器是蹩脚的!!

很简单,有没有办法说类似..

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

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

(请注意,另一种方法是“链接”过程......所以在“otherStuff”结束时,您和所有其他程序员必须“知道”接下来您必须调用“moreStuff”,无论otherStuff 如何发挥作用,等等。当然,当您必须添加新程序或更改事物的顺序时,这会非常混乱。)干杯!!

顺便说一句,当您想要不同的线程时,下面已经有两个很好的答案。

【问题讨论】:

  • 我认为你应该考虑 NSLock 和 NSCondition。它比无限循环更合适。
  • 我只是好奇。为什么需要这样的内联解决方案?
  • malex -- 嗯,我真的不明白 NSLocking 在这里有什么帮助。也许我错过了一些东西。 Andrey - 查看第一个示例虚构代码块。移动项目、添加项目等将非常容易/优雅。继续写一个非内联解决方案!
  • 你还在等什么?
  • sleep(1000000) 会满足您的问题吗? waithere可以恢复吗,如果可以,什么时候恢复?

标签: ios objective-c semaphore promise nsnotificationcenter


【解决方案1】:

这是一个使用信号量的解决方案,注意不要引入死锁 - 你需要某种方式告诉你的应用程序已经完成,你可以像你建议的那样使用 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];

【讨论】:

  • 奥利弗,非常感谢你......啊。那么现在......这完全发生在“同一”线程上,对吗? (即:您不必将 someOtherStuffWithCompletion 发送到另一个线程或类似的东西?)谢谢!
  • TBC,当你说避免死锁时,你的意思是:“不要忘记”最终调用 dispatch_semaphore_signal?或者更可怕的东西我不明白? :) 谢谢!
  • someOtherStuffWithCompletion 需要在另一个线程上发生,你是对的
  • 啊,另一个线程,我明白了——废话!我正在同一线程上寻找解决方案。该死的,我必须把问题说清楚,对不起!不过仍然非常有用........再次感谢
  • 如果你在同一个线程上工作,那么你不需要等待,下一个操作只会在前一个操作完成后执行——这就是计算机的工作方式。
【解决方案2】:

我建议使用 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

【讨论】:

  • 很棒的想法——但是这些人都会在不同的线程上,对吧?
  • 如果您将 maxConcurrentOperationCount 设置为 1,则不会。
  • Marcio 完全正确。我更新了上面的代码示例以反映这种行为。
  • 嗯,伙计们,我想知道,如果您设置 .maxConcurrentOperationCount = 1,是否会将它们全部放在(1)新(不同)线程上?或者它是否将所有这些都放在“我们的”同一个线程上?干杯....
  • 在一个新的不同线程中。但是我认为您希望将所有内容都放在同一个线程中。或者可能在主线程上?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-19
  • 1970-01-01
  • 2019-05-27
  • 2021-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多