2011-08-28 12 views
86
計算器的

尊敬的好人,NSDefaultRunLoopMode VS NSRunLoopCommonModes

就像是最後一次,我在此帶來了一個問題,我最近在跌倒。我希望那裏有人能夠給我一些啓示。

每當我嘗試下載UIScrollViewMPMapView或其他東西后面的大文件時,只要我觸摸iPhone屏幕,下載過程就會暫停。值得慶幸的是,一篇由Jörn撰寫的博客帖子提出了一個替代方案,使用NSRunLoopCommonModes進行連接。

那讓我看看這兩種模式,NSDefaultRunLoopMode和NSRunLoopCommonModes的細節,但蘋果的文檔不會善待解釋,除了說

NSDefaultRunLoopMode

的方式處理其他輸入源比NSConnection對象。 這是最常用的運行循環模式。

NSRunLoopCommonModes

對象添加到使用這個值作爲模式由已被聲明爲組的「共同的」模式中的成員的所有運行的循環模式監視的運行循環;見CFRunLoopAddCommonMode的說明了解詳情。

CFRunLoopAddCommonMode

來源,定時器s,並且觀察者會註冊到一個或多個運行循環模式,並且只有在運行循環以這些模式之一運行時纔會運行。常用模式是一組運行循環模式,您可以爲其定義由這些模式共享的一組源,定時器和觀察器。例如,不要將源註冊到每個特定的運行循環模式,而是將其註冊一次到運行循環的公共僞模式,並且將在共模模式下的每個運行循環模式中自動註冊。同樣,當模式被添加到一組共同模式時,已經註冊到公共僞模式的任何源,定時器或觀察者都被添加到新添加的共模中。

誰能請解釋人類語言的兩個?

回答

164

運行循環是一種機制,允許系統喚醒睡眠線程,以便它們可以管理異步事件。通常當你運行一個線程(除了主線程)之外,還有一個選項可以在運行循環中啓動線程。如果線程運行某種排序或長時間運行的操作而沒有與外部事件和定時器交互,則不需要運行循環,但是如果線程需要響應傳入事件,則應該將其附加到運行循環以便當新事件到達時喚醒線程。這是NSURLConnection生成的線程的情況,因爲它們僅在傳入事件(來自網絡)時喚醒。

每個線程可以關聯到多個運行循環,或可以被關聯到可設定在不同的模式工作的特定運行循環。 「運行循環模式」是操作系統用來確定何時傳送某些事件或收集它們以便稍後傳送的一些規則的慣例。

通常所有的運行循環都設置爲「默認模式」,它建立了管理輸入事件的默認方式。例如:一旦鼠標拖拽(Mac OS)或觸摸(在iOS上)事件發生,則此運行循環的模式設置爲事件跟蹤;這意味着線程不會在新的網絡事件中被喚醒,但當用戶輸入事件終止並且運行循環再次設置爲默認模式時,這些事件將在稍後傳遞;顯然,這是操作系統架構師選擇用戶事件而不是後臺事件的選擇。

如果您決定改變運行循環模式供您NSURLConnection線程,通過使用scheduleInRunLoop:forModes:,那麼你可以線程分配給一個特殊的運行循環模式,而不是特定的默認運行循環。稱爲NSRunLoopCommonModes的特殊僞模式被許多輸入源使用,包括事件跟蹤。例如,將NSURLConnection的實例分配給通用模式意味着除了「默認模式」之外,還將其事件與「跟蹤模式」相關聯。將線程與NSRunLoopCommonModes關聯的一個優點/缺點是線程不會被觸摸事件阻塞。

可以將新模式添加到常用模式,但這是相當低級的操作。

我想通過增加幾個音符關閉:

  • 通常我們需要用一組圖片或 縮略圖從表視圖網絡下載。我們可能認爲 從網絡下載這些圖像,而表格視圖是 滾動可以改善用戶體驗(因爲我們可以在滾動時看到圖像,而 滾動),但這不是有利的,因爲滾動的流動性會受到很大的影響。在這個例子中,NSURLConnection不應該使用運行循環;最好使用UIScrollView委託方法來檢測滾動何時終止,然後更新表格並從網絡下載新項目 ;

  • 您可以考慮使用GCD,它可以幫助您屏蔽代碼 免受運行循環管理問題的影響。在上面的例子中,您可能會考慮將您的網絡請求添加到自定義串行隊列中。

+6

親愛的Viggio24,非常感謝你對這個乾淨,精確的解釋。我會要求Apple將你的評論加入他們的API指南。 ;) – Stkim1

+0

我upvoted你的答案,因爲是絕對清楚!感謝您分享您的知識。 –

+3

** viggio24 **的回答是完美的。對於那些感興趣的人,我會指出**來自WWDC 2010的**會話208(適用於iPhone OS的網絡應用程序,第2部分)**包含運行循環介紹。如果你有興趣看看。希望能幫助到你。 –

相關問題