9

我希望在当前方法通过并且 UI 已更新后执行一个方法。为此,我现在正在使用[object performSelector:@selector(someSelector) withObject:someObject afterDelay:0.0]。根据Apple 的文档,这会创建一个 NSTimer,然后它将触发选择器并将其附加到当前的 NSRunLoop。但我不认为这很优雅。有没有一种简单的方法可以将选择器直接排入当前运行循环,而无需 Cocoa 创建 Timer 等?

performSelectorOnMainThread:withObject:waitUntilDone:(如果我在主线程上)或者performSelector:onThread:withObject:waitUntilDone:waitUntilDone:NO更少的开销做我想做的事?

提前欢呼和感谢

法师先生

4

5 回答 5

6

Cocoa 是事件驱动的。您不会“在当前运行循环中将选择器排入队列”。简单地说:发送到应用程序的事件(用户输入、计时器、网络活动......)会导致运行循环运行,这会导致循环运行中发生事情。当然有“细节”,但这是最基本的行为。

如果您想推迟执行某些选择器到当前运行循环的末尾,请最后调用它,或者要求它在(非常接近)即将到来的循环运行时运行。-performSelector:... 方法执行此操作的正确方法。他们创建了一个计时器,该计时器会导致导致事情发生的事件。

有关更多信息,请参阅Cocoa 事件处理指南

于 2009-11-14T16:21:14.300 回答
4

我没有看到您突出显示的 -performSelector:withObject:afterDelay: 方法有任何不雅之处。这个方法只是简单地将一个任务排入队列,在当前的run loop循环完成后执行。从您链接到的部分中的文档

在下一个运行循环周期和可选的延迟期之后,在当前线程上执行指定的选择器。因为它会等到下一个运行循环周期来执行选择器,所以这些方法提供了当前执行代码的自动最小延迟。多个排队选择器按照它们排队的顺序一个接一个地执行。

没有创建 NSTimer 对象来管理它,选择器只是在一定延迟后排队运行(小的延迟意味着在运行循环周期完成后立即运行)。对于您希望在 UI 更新后发生的操作,这是最简单的技术。

对于更明确的线程队列,您可以查看NSOperationsNSOperationQueues。maxConcurrentOperationCount 为 1 的 NSOperationQueue 可以按顺序运行操作,一个接一个。

于 2009-11-14T20:23:45.447 回答
4

I prefer the NSRunLoop method "performSelector:target:argument:order:modes:". It's guaranteed to not execute the selector until the next iteration of the run loop, and you don't have to mess around with specifying arbitrary delays, etc.

于 2009-11-15T20:19:20.110 回答
2

我自己已经多次使用过这种技术,我认为它并没有那么不雅......但是,您可以尝试的替代方法是:

performSelectorOnMainThread:withObject:waitUntilDone:NO.

Just because you are already on the main thread, does not mean it would not work (in fact the documents reference behaviour that will happen when called from the main thread)... and I think it would have the same behavior when waitUntilDone is set to NO, where it queues up the request to execute the selector and have it run when the current run-loop ends.

于 2009-11-14T21:16:02.830 回答
0

Just for completeness sake I'd like to add this solution, which would be the appropriate one if we want to be nitpicking ;)

[[NSOperationQueue currentQueue] addOperationWithBlock:^{
    // will be with you in a moment...
}];
于 2022-03-06T03:42:01.590 回答