我希望在当前方法通过并且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
答案 0 :(得分:6)
Cocoa是事件驱动的。你没有“在当前的运行循环中排队选择器”。简单地说:发送到应用程序的事件(用户输入,计时器,网络活动......)导致运行循环运行,这导致在循环运行中发生的事情。当然有“细节”,但这是最基本的行为。
如果你想推迟在当前运行循环结束时执行一些选择器,最后调用它,或者要求它在(非常接近的)即将运行的循环运行。 -performSelector:... methods 是执行此操作的正确方法。他们创建了一个计时器,导致事件发生。
有关详细信息,请参阅Cocoa Event-Handling Guide。
答案 1 :(得分:4)
我没有看到关于-performSelector的任何不雅之处:withObject:afterDelay:你突出显示的方法。该方法简单地将在运行循环的当前循环完成之后执行的任务排队。来自documentation in the section you linked to:
执行指定的选择器 下一次运行时的当前线程 循环周期和可选的延迟之后 期。因为它等到了 下一次运行循环循环来执行 选择器,这些方法提供了一个 自动迷你延迟 目前执行代码。多 排队选择器执行一个 接下来是他们的顺序 排队。
没有创建NSTimer对象来管理它,选择器只是在一定延迟后排队运行(一个小延迟意味着在运行循环周期结束后立即运行)。对于您希望在更新UI后发生的操作,这是最简单的技术。
对于更明确的线程排队,您可以查看NSOperations和NSOperationQueues。 maxConcurrentOperationCount为1的NSOperationQueue可以按顺序依次运行操作。
答案 2 :(得分:4)
我更喜欢NSRunLoop方法“performSelector:target:argument:order:modes:”。它保证在运行循环的下一次迭代之前不执行选择器,并且您不必乱用指定任意延迟等。
答案 3 :(得分:2)
我自己多次使用过这种技术,而且我觉得它不那么优雅......但是,你可以尝试的另一种方法是:
performSelectorOnMainThread:withObject:waitUntilDone:NO
。
仅仅因为你已经在主线程上,并不意味着它不起作用(实际上是从主线程调用时会发生的文档引用行为)...而且我认为它会有相同的行为waitUntilDone设置为NO,它将执行选择器的请求排队,并在当前运行循环结束时运行。