天天看點

Cocoa:NSOperation和NSOperationQueue

    Cocoa: NSOperation和NSOperationQueue

    在任何語言中多線程處理都是麻煩的。更糟糕的是如果出錯了往往會以很壞的方式出錯。鑒于此,程式員要麼完全避免使用多線程(把它當做邪惡之源),要麼發很長的時間來確定每個方面都很完美。

    慶幸的是,Apple在OS X 10.5 Leopard上做了很多改進。NSThread本身就新增了很多新的方法,進而使得多線程變得更加容易。此外還新增了NSOperation和NSOperationQueue兩個類。該教程通過一個簡單的執行個體來介紹如何使用這些新增類并如何讓多線程的應用變得小菜一碟。

   你可以從此擷取該項目的執行個體代碼: Async Downloader Example Project

    在該教程中,我會介紹一種使用NSOperation和NSOperationQueue在背景線程中很好地處理任務的方法。該教程的目标是介紹這些類的使用,但并不排除使用它們的其他方法。

如果你熟悉Java或一個它的變種語言,NSOperation就和java.lang.Runnable接口很相似。和Java的Runnable一樣,NSOperation也是設計用來擴充的,并且最低僅需重寫一個方法。對于NSOperation這個方法是-(void)main。一個使用NSOperation的最簡單方法就是将其放入NSOperationQueue中。一旦一個操作被加入隊列,該隊列就會啟動并開始處理它。一旦該操作完成隊列就會釋放它。

<b>NSOperation</b><b>執行個體</b>

在該執行個體中,我編寫了一段擷取網頁内容的字元串,然後解析成NSXMLDocument對象并在結束前傳回應用主線程。

<b>PageLoadOperation.h</b>

<b>PageLoadOperation.m</b>

我們可以看到,這個類很簡單。它在init方法中接受一個URL并儲存起來。在調用main方法的時候它就從URL中建構一個字元串并傳給NSXMLDocument的init方法。如果在加載xml文檔過程中沒有發生錯誤,該文檔就會被傳回到主線程的AppDelegate,然後任務結束。隊列會在NSOperation的main方法結束後自動釋放該對象。

<b>AppDelegate.h</b>

<b>AppDelegate.m</b>

在執行個體中AppDelegate做了兩件事。其一是在init方法中初始化了NSOperationQueue并載入了一個urls數組。在應用結束加載時NSApplication 執行個體會調用applicationDidFinishLaunching:方法,AppDelegate就周遊每個url并建立相應的任務,然後将任務加入隊列中。在隊列中每加入一個人後,隊列都會為其配置設定一個NSThread來啟動它,線程就會運作操作的main方法。一旦操作完成,線程就會報告給隊列以讓隊列釋放該操作。

<b>NSOperationQueue</b><b>的并發</b>

在這個簡單的執行個體中,由于很難再隊列中加入足夠多的任務使得我們很難看到它們是并發運作的。但如果你的任務需要更多的時間,你就可以看到隊列是同時運作所有的任務。如果你想限制并行運作的任務數目,你可以在AppDelegate的init方法中做如下修改。

在這個修改的init方法中,隊列被限制隻能同時運作兩個操作。剩餘的操作就需要等待之前的兩個操作有一個完成後才有機會被運作。

<b>結論</b>

這是NSOperation和NSOperationQueue最基本的使用。你可以注意到該執行個體的大部分代碼和NSOperation和NSOperationQueue 的設定和使用無關。NSOperation所需要的代碼是驚人地少。但是通過這少量的代碼你就可以在你的應用中輕松地使用多線程以為使用者提供更好的使用者體驗并可以更好地優化複雜任務。

原文連結:http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/

繼續閱讀