performSelector:withObject:afterDelay:和dispatch_after之间有什么权衡

时间:2011-06-01 18:33:10

标签: iphone objective-c ios ios4 grand-central-dispatch

我遇到的唯一功能差异是我可以取消使用performSelector:withObject:afterDelay:安排的消息。我不知道如何取消提交给dispatch_after的阻止。 (请告诉我是否有办法做到这一点,我不知道)。

我想了解更多关于:

  • 功能权衡(用一个接口可以完成什么,但不能用另一个接口完成?)
  • 性能权衡(一种实现更有效吗?在哪些情况下?)
  • 样式权衡(我是否更喜欢某个任务的界面,以更好地遵循常见的样式或约定?)

2 个答案:

答案 0 :(得分:19)

dispatch_after是新Grand Central Dispatch的一部分,它是iOS的扩展,旨在改善多核硬件上的并发代码执行。

但总的来说,我认为它们总体上满足了不同的要求。 GCD允许对代码的并发执行进行更精细的分级控制。您可以在队列中调度块,删除它们,暂停,恢复等。这是一个更广泛的主题,在这里一般要考虑。此外,GCD还提供了更多的同步选项。

就与performSelector的比较而言,我认为dispatch_after正确的一个优势是可以在不需要定义选择器的情况下调度块。 请参阅this discussion

总而言之,我对GCD没有多少经验,但我会说除了块调度之外,当你只需要在你的UI中延迟一些选择器执行时,一般不需要并发,我会使用performSelector

如果您考虑一下,performSelector会给您一个非常差的并发性,因为它只是在最短的时间后调度您的选择器以在运行循环上执行。另一方面,dispatch_after给你一个原则上似乎在纳秒级别的控件(!!这是我从Apple文档获得的,但我从来没有使用它,我不认为你会得到iPhone,可能在MacOS上。)

编辑:关于取消调度一个块,我从来没有尝试从队列中取消调度块,但dispatch_release也有可能让你控制它。如果没有,您可以为要取消的块定义自定义队列并释放整个队列(在块开始执行之前),如果这对您有意义的话。

至于性能,我真的不知道里面有performSelector做什么,但是如果它调度一个线程,那么使用GCD调度块的Apple states只需要15条指令,同时创建一个线程花费了数百个。

除了performSelector之外,不要忘记你可以选择使用基于GCD的NSOperationQueue,并且有一些开销,但不是那么大,他们说。 NSOperationQueue肯定会提供取消的可能性。

答案 1 :(得分:4)

使用GCD代替performSelector的另一大优势是能够非常简单地使用多个局部变量作为块操作的一部分。如果要延迟执行带有多个参数的方法,直到稍后使用performSelector,则必须将要使用的参数包装在另一个对象(如数组)中。使用dispatch_after,您可以非常简单地将任意数量的局部变量传递给块。这也适用于非对象,如果没有先包装在对象中,则无法传递给performSelector调用,例如NSValue用于传递CGRect。 GCD允许您将基元,结构和对象传递给要延迟的操作。