【问题标题】:What are the tradeoffs between performSelector:withObject:afterDelay: and dispatch_afterperformSelector:withObject:afterDelay: 和 dispatch_after 之间的权衡是什么
【发布时间】:2011-09-06 13:16:38
【问题描述】:

我遇到的唯一功能差异是我可以取消使用performSelector:withObject:afterDelay: 安排的消息。我不知道有什么方法可以取消提交给dispatch_after 的块。 (如果有我不知道的方法,请告诉我)。

我想了解更多:

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

【问题讨论】:

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


    【解决方案1】:

    使用 GCD 代替 performSelector 的另一大优势是能够非常简单地使用多个局部变量作为块操作的一部分。如果您想使用performSelector 将采用多个参数的方法的执行推迟到稍后时间,您必须将要使用的参数包装在另一个对象中,例如数组。使用dispatch_after,您可以非常简单地将任意数量的局部变量传递给块。这也适用于非对象,如果不首先包装在对象中,就无法将其传递给performSelector 调用,例如用于传递CGRectNSValue。 GCD 允许您将原语、结构和对象传递给您想要延迟的操作。

    【讨论】:

      【解决方案2】:

      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里面做了什么,但是如果它调度一个线程,那么Applestates用GCD调度一个块只需要15条指令,而创建一个线程需要几百条指令其中。

      除了performSelector,别忘了你可以选择使用NSOperationQueue,它基于GCD,并且有一些明显的开销,但不是那么大,他们说。 NSOperationQueue 当然提供取消的可能性。

      【讨论】:

      • 感谢您的回复。我从未见过将块安排在队列中后删除它们的方法。你能提供更多细节吗?此外,除了并发之外,一个接口在串行执行方面是否比另一个更有效?
      • 如果我对 sergio 的理解正确,他建议释放队列将取消所有待处理的块的执行。不是这样的...参见developer.apple.com/library/mac/#documentation/Performance/…,它说:当您的应用程序不再需要调度队列时,它应该使用 dispatch_release 函数释放它。提交到队列的任何待处理块都持有对该队列的引用,因此在所有待处理块完成之前不会释放队列。
      • 你也可以创建一个gcd定时器,可以取消:fieryrobot.com/blog/2010/07/10/a-watchdog-timer-in-gcd
      • Note: Even if you specify a leeway value of 0, you should never expect a timer to fire at the exact nanosecond you requested. The system does its best to accommodate your needs but cannot guarantee exact firing times. 来自苹果文档:developer.apple.com/library/ios/#documentation/General/…
      • 使用 GCD 调度一个花费 15 条指令的块是指 dispatch_async,而不是 dispatch_after。 dispatch_after 会比这慢得多,因为任何使用计时器的东西都会这样。
      猜你喜欢
      • 2015-10-29
      • 2017-01-13
      • 1970-01-01
      • 1970-01-01
      • 2021-09-05
      • 1970-01-01
      • 2021-09-29
      • 1970-01-01
      • 2011-08-12
      相关资源
      最近更新 更多