NSDefaultRunLoopMode vs NSRunLoopCommonModes

Whenever I try to download a big file behind UIScrollView, MPMapView or something, the downloading process gets halted as soon as I touch iPhone screen. Thankfully, an awesome blog post by Jörn suggests an alternative option, using NSRunLoopCommonModes for connection.

That gets me look into detail of the two modes, NSDefaultRunLoopMode and NSRunLoopCommonModes, but the apple document does not kindly explain, other than saying

NSDefaultRunLoopMode

The mode to deal with input sources other than NSConnection objects. This is the most commonly used run-loop mode.

NSRunLoopCommonModes

Objects added to a run loop using this value as the mode are monitored by all run loop modes that have been declared as a member of the set of “common" modes; see the description of CFRunLoopAddCommonMode for details.

CFRunLoopAddCommonMode

Sources, timers, and observers get registered to one or more run loop modes and only run when the run loop is running in one of those modes. Common modes are a set of run loop modes for which you can define a set of sources, timers, and observers that are shared by these modes. Instead of registering a source, for example, to each specific run loop mode, you can register it once to the run loop’s common pseudo-mode and it will be automatically registered in each run loop mode in the common mode set. Likewise, when a mode is added to the set of common modes, any sources, timers, or observers already registered to the common pseudo-mode are added to the newly added common mode.

Can anyone please explain the two in human language?

30705 次浏览

运行循环是一种机制,它允许系统唤醒睡眠线程,以便它们可以管理异步事件。通常,当您运行一个线程(除了主线程)时,有一个选项可以选择是否在运行循环中启动该线程。如果线程运行某种排序或长时间运行的操作,没有与外部事件交互,也没有计时器,那么您不需要运行循环,但是如果您的线程需要响应传入事件,那么它应该附加到一个运行循环,以便在新事件到达时唤醒线程。这就是 NSURLConnection生成的线程的情况,因为它们只在传入事件(来自网络)上唤醒。

每个线程可以关联到多个运行循环,或者可以关联到可以设置为在不同模式下工作的特定运行循环。“运行循环模式”是操作系统使用的一种约定,用于建立一些规则,以便在何时交付某些事件或收集它们以便以后交付。

Usually all run loops are set to the "default mode" which establishes a default way to manage input events. For example: as soon as a mouse-dragging (Mac OS) or touch (on iOS) event happens then the mode for this run loop is set to event tracking; this means that the thread will not be woken up on new network events but these events will be delivered later when the user input event terminates and the run loop set to default mode again; obviously this is a choice made by the OS architects to give priority to user events instead of background events.

If you decide to change the run loop mode for your NSURLConnection thread, by using scheduleInRunLoop:forModes:, then you can assign the thread to a special run loop mode, rather than the specific default run loop. The special pseudo-mode called NSRunLoopCommonModes is used by many input sources including event tracking. For example assigning NSURLConnection's instance to the common mode means associates its events to "tracking mode" in addition to the "default mode". One advantage/disadvantage of associating threads with NSRunLoopCommonModes is that the thread will not be blocked by touch events.

可以将新模式添加到常见模式中,但这是一个相当低级的操作。

最后,我想补充几点:

  • 通常我们需要使用一组图像或 从网络上下载的带有表格视图的缩略图。我们可能认为 从网络下载这些图像,而表视图是 滚动可以改善用户体验(因为我们可以看到的图像,而 滚动) ,但这不是有利的,因为流动性 scrolling can suffer greatly. In this example with NSURLConnection a run loop should not be used; it would be better to use the UIScrollView delegate methods to detect when scrolling is terminated and then update the table and download new items 来自网络;

  • 您可以考虑使用 GCD,它将帮助您“屏蔽”您的代码 从运行循环管理问题。在上面的示例中,您可以 考虑将您的网络请求添加到自定义串行队列中