将选择器排入运行循环 - 是[NSObject performSelector:withObject:afterDelay:]的方法吗?

时间:2009-11-14 16:14:59

标签: iphone objective-c cocoa cocoa-touch runloop

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

performSelectorOnMainThread:withObject:waitUntilDone:(如果我在主线程上)或performSelector:onThread:withObject:waitUntilDone: waitUntilDone:NO会以更少的开销执行我想要的工作吗?

提前干杯和谢谢

MrMage

4 个答案:

答案 0 :(得分:6)

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

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

有关详细信息,请参阅Cocoa Event-Handling Guide

答案 1 :(得分:4)

我没有看到关于-performSelector的任何不雅之处:withObject:afterDelay:你突出显示的方法。该方法简单地将在运行循环的当前循环完成之后执行的任务排队。来自documentation in the section you linked to

  

执行指定的选择器   下一次运行时的当前线程   循环周期和可选的延迟之后   期。因为它等到了   下一次运行循环循环来执行   选择器,这些方法提供了一个   自动迷你延迟   目前执行代码。多   排队选择器执行一个   接下来是他们的顺序   排队。

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

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

答案 2 :(得分:4)

我更喜欢NSRunLoop方法“performSelector:target:argument:order:modes:”。它保证在运行循环的下一次迭代之前不执行选择器,并且您不必乱用指定任意延迟等。

答案 3 :(得分:2)

我自己多次使用过这种技术,而且我觉得它不那么优雅......但是,你可以尝试的另一种方法是:

performSelectorOnMainThread:withObject:waitUntilDone:NO

仅仅因为你已经在主线程上,并不意味着它不起作用(实际上是从主线程调用时会发生的文档引用行为)...而且我认为它会有相同的行为waitUntilDone设置为NO,它将执行选择器的请求排队,并在当前运行循环结束时运行。