17

我需要一种保存方式说:“iOS,我希望这个方法尽快执行,但不要在本次运行循环迭代中。最早在下一次,但请不要在本次中。谢谢。”

现在我总是这样做:

[self performSelector:@selector(doSomethingInNextRunLoop) withObject:nil afterDelay:0];
[self doSomeOtherThings];

假设-doSomeOtherThings将始终执行 BEFORE -doSomethingInNextRunLoop

文档说:

指定延迟为 0 不一定会导致选择器立即执行。选择器仍在线程的运行循环中排队并尽快执行。

所以基本上它可能会立即调用该方法,就好像我刚刚发送了一条直接消息,导致-doSomethingInNextRunLoop之前执行-doSomeOtherThings

我怎样才能绝对确定它会被尽快调用,但永远不会在同一个运行循环迭代中调用?

为了澄清措辞:对于运行循环,我指的是主线程,以及所有方法必须返回的迭代,直到线程再次为新事件做好准备。

4

4 回答 4

10

如果您担心 Apple 某天可能会将延迟设为 0,那么您始终可以指定延迟为 1e-37 左右。虽然performSelector:withObject:afterDelay:可以很容易地阅读文档以保证选择器将始终安排在下一次运行循环迭代中。

如果您担心 Apple 某天可能会在特殊情况下延迟小于某个任意下限,您可以随时尝试使用 NSRunLoop performSelector:target:argument:order:modes:,文档明确指出它将为运行循环的下一次迭代安排执行。

于 2011-08-17T16:53:12.773 回答
7

使用 GCD(Grand Central Dispatch)非常简单:

dispatch_async (dispatch_get_main_queue (), ^{
    NSLog (@"This stuff runs in the next iteration of the main run loop");
});
于 2014-03-18T12:06:26.667 回答
1

我认为您从阅读文档中得出的结论是错误的。

所以基本上它可能会立即调用该方法,就好像我刚刚发送了一条直接消息一样

不,您引用的文档部分说选择器始终在运行循环中排队,无论如何。所以它永远不会像直接消息一样被执行。

带有“不一定”的第一句话可能有点误导,但我认为第二句话应该真正澄清你担心的事情不会发生。

于 2011-08-17T17:47:11.907 回答
0

当然,您只是这样做;

[self doSomeOtherThings];
[self performSelector:@selector(doSomethingInNextRunLoop) withObject:nil afterDelay:0];

这保证了您想要的执行顺序。

于 2011-08-17T16:50:34.187 回答