在您更新的問題中,是的,我認爲通知中心是後臺網絡任務在新數據可用時更新視圖控制器的完美方式。
你問:
應視圖控制器不斷地監聽更新通知?
的排序。 「不斷傾聽」一詞可能意味着它經常檢查更新。顯然,這並不是真的(或者更重要的是,你不希望它這樣做)。相反,它只是將自己註冊爲該通知的觀察者(並且確保何時視圖被駁回,也不會註冊)。這樣,它會被通知你的任何自定義通知,但它不會浪費很多CPU週期「不停地收聽」。
您再進行後續,問:
我的想法是,一個視圖控制器寄存器作爲觀察員,填充與模型數據的視圖(無論空數據),並自動更新上接收到通知,即從現在具有「最新」數據的模型中獲取數據。這將所有網絡呼叫從視圖控制器中移出,允許視圖控制器訪問共享數據。思考?
基本上,是的,這聽起來不錯。我對此的唯一細微改進是,我會預先在應用程序數據庫中用數據當前數據發佈應用程序到商店。這樣,用戶有東西看應用程序正在檢索最新的數據。也許這在你的場景中是無效的,但是當應用程序檢索最新和最好的時候,往往最好向用戶展示一些東西(即使有點過時),而不是一無所獲。
最後(你可能已經在考慮這個了),我會確保向用戶展示數據正在後臺下載的一些視覺指示。也許是一個良好的UIActivityIndicatorView
(即一個微調)或UIProgressView
。也許更新UIRefreshControl
的文本以表明正在處理桌面瀏覽的下載正在進行中。也許還可以更新狀態欄中的網絡活動指示器。
我敢肯定,每個人都有自己的方法來此,但這裏有什麼,我在一個應用程序,數據檢索過程是複雜的做了一些看法,恰巧完全異步,並且應用程序可以正常進行,而下載/處理正在進行中:
除了標準模型,視圖和視圖控制器類,我有一個單獨的「XML控制器」,其做的結果的下載和解析。我讓它異步啓動下載。
爲了方便xml控制器和視圖控制器之間的通信,我使用了通知。這樣xml控制器就會發布關於下載/解析過程的開始和完成特定階段的通知。如果視圖控制器在更新過程中不可靠,則視圖控制器可以在開始時呈現微調器,並且/或者在相應的特定下載/解析階段完成後相應地刷新自己。必須注意確定所有應用層併發問題。在每個步驟中,您都必須處理「如果在後臺隊列中更改模型數據會發生什麼情況會怎樣」。
底線,當進行異步更新時,防禦性編程是一天的規則。你根本無法做出假設,只是因爲你最近檢索了一些即使在稍後有效的東西。我們在代碼中輕鬆做出的許多假設都不再成立。我也會更加關注基於某種索引的任何操作(例如「第5項」),並且肯定傾向於基於鍵的操作(例如「具有唯一標識符4027的項目」)。
就數據庫層併發性問題而言,它取決於持久性存儲的性質。如果您使用的是核心數據,請參閱討論併發性的WWDC 2012 - 214 Best Practices with Core Data。或者參見核心數據編程指南中的Concurrency with Core Data。如果使用SQLite,一個簡單的解決方案是有一個專用的數據庫操作的串行隊列,如FMDB'sFMDatabaseQueue
。順便說一下,如果您使用後一種方法,您將需要確保將數據庫交互分解爲儘可能最小的操作,以避免捆綁數據庫。
如果您想讓用戶瞭解異步下載/更新過程的進度,您可能需要考慮您的框架。有些應用程序的操作與狀態欄中的網絡活動指示器一樣簡單。其他人更新某些公共導航欄中的某些狀態消息。我還爲我的通知使用了自定義容器,這樣我就不必在每個視圖控制器中添加「顯示用戶狀態更新」。這裏有很多方法,但是您應該避免使用在每個視圖控制器中包含狀態更新代碼的解決方案(顯然,如果視圖控制器依賴於由背景隊列修改的當前項目,這種情況不是狀態更新問題,而是應用程序流問題)。
來源
2013-02-16 15:55:08
Rob
謝謝您的全面評論,非常感謝。我有一些後續問題,請參閱修訂後的問題 – SkeetSkeet 2013-02-20 13:30:20
@SkeetSkeet我同意您在修訂後的問題中的很多觀察結果。但我已經相應地更新了我的答案。 – Rob 2013-02-20 14:01:33
非常感謝您花時間提供非常有幫助的答案,並指引我朝着正確的方向發展! UIRefreshControl將在公衆準備好iOS 6時立即實施:) – SkeetSkeet 2013-02-21 16:50:16