iOS多線程編程

來源:互聯網
上載者:User

標籤:

iOS多線程編程

 

1. 進程,線程, 任務

   進程:一個程式在運行時,系統會為其分配一個進程,用以管理他的一些資源。

   線程:進程內所包含的一個或多個執行單元稱為線程,線程一般情況下不持有資源,但可以使用其所在進程的資源。

   任務:進程或線程中要做的事情。

 

   在引入線程的作業系統中,通常把進程作為分配資源的基本單位,而把線程作為獨立運行和獨立調度的基本單位。

    線程比進程更小,對其調度的開銷小,能夠提高系統內多個任務的並發執行程度。

    一個程式至少有一個進程,一個進程至少有一個線程.一個程式就是一個進程,而一個程式中的多個任務則被稱為線程。

    線程只能歸屬於一個進程並且它只能訪問該進程所擁有的資源。當作業系統建立一個進程後,該進程會自動申請一個名為主線程或首要線程的線程。應用程式(application)是由一個或多個相互協作的進程組成的。

    多線程的意義在於一個應用程式中,有多個執行部分可以同時執行。提供協調機制,一方面防止進程之間和線程之間產生衝突,另一方面允許進程之間和線程之間共用資源。

    

2. iOS多線程編程技術

    共有三種(實際上是四種,還有Pthreads,C語言架構)

    > NSThread

    > NSOperation

    > GCD (Grand Central Dispatch)

    從上到下,封裝度從低到高,封裝度越高使用越簡單,也是官方推薦使用。

    

    三種方式的比較:

    NSThread:  相對於另外兩種是比較輕量級的。此種方式是經官方封裝後的,是完全物件導向的,所以可以直接操控線程對象,非常直觀方便。但是需要自己管理線程的生命週期,線程同步,而且線程同步對資料的加鎖會有一定的系統開銷。使用比較簡單,但不夠智能,在一些簡單的情境才使用。

    NSOperation: 完全物件導向的。相關的主要類有 NSOperation(任務) 和 NSOperationQueue(任務隊列),其中NSOperationQueue 在iOS4引入GCD後,其內部用GCD實現的。此種方式下不需要關心線程管理,資料同步的操作。隱藏了許多複雜的代碼,提供了簡單的API。

    GCD : 是蘋果為多核並行運算提出的解決方案,會自動合理的利用更多的CPU核心(如雙核,四核)。此種方式也能自動管理線程的生命週期(建立線程,調度任務,銷毀線程),不需要自己管理,只需要告訴其要做的操作是什麼就可以。雖然也使用c語言,但因為使用了block, 使用也很方便,靈活。在GCD中也有“任務”,“隊列”的概念。

  

 

一、NSThread  ===========================================

1. 使用NSThread建立並管理線程

   > 建立線程

      方式一:執行個體方法

      [NSThread alloc] initWithTarget: selector : object:]

      參數一:線程操作訊息的接收者 self

      參數二:選取器方法,線程操作的方法,此方法只能帶一個參數,而且不能有傳回值

      參數三:線程操作方法所帶的參數

      使用該方式建立的線程不會自動啟動,需調用線程方法:

      [thread start]  // 開始啟動並執行線程

      方式二:類方法

      [NSThread detachNewThreadSelector: toTarget: withObject: ]

      參數同上同名參數;

      此方法建立的線程會自動啟動執行,無需手動開啟。

    > 線程方法

       //取消線程

       - (void)cancel;

       //啟動線程

       - (void)start;

       //設定/擷取某個線程的狀態

       @property (readonly, getter=isExecuting) BOOL executing;

       @property (readonly, getter=isFinished) BOOL finished;

       @property (readonly, getter=isCancelled) BOOL cancelled;

       //設定和擷取線程名字

       -(void)setName:(NSString *)n;

       -(NSString *)name;

       //擷取當前線程

       + (NSThread *)currentThread;

       //擷取主線程

       + (NSThread *)mainThread;

       //使當前線程暫停一段時間,或者暫停到某個時刻

       + (void)sleepForTimeInterval:(NSTimeInterval)time;

       + (void)sleepUntilDate:(NSDate *)date;

       // 設定線程優先順序

       + (BOOL)setThreadPriority:(double)p;

      > 線程間的通訊

       在非主線程上絕對不能去訪問UI, 必須在主線程上更新

       [self performSelectorOnMainThread:@selector(updateUI:) withObject:data waitUntilDone:YES];

       線程與線程間可進行資料通訊

       [self performSelector:@selector(senddata:) onThread:thread2 withObject:obj waitUntilDone:YES]

      > 線程同步

        多個線程訪問同一共用資源時,為保證資料資源的準確性,需對資源進行加鎖,是在一個時刻上只有一個線程訪問共用資源,其他線程則排隊等待。

         NSLock 鎖

         [[NSLock alloc] init]

         [theLock lock];

         …..要訪問的共用資源

         [theLock unlock];

      

二、NSOperation========================================================

1. NSOperation

   此類是抽象類別不能直接使用。

   只能使用系統定義好的子類或者自訂繼承NSOperation。

   定義好的子類:NSInvocationOperation 和 NSBlockOperation

   一個 NSOperation對象 對應一個任務/線程,需要將其放入 NSOperationQueue 任務隊列/線程池,才會啟動並執行任務/線程。 

 2. NSInvocationOperation

   任務的操作執行在方法中進行

   > [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(..) object:nil]   

 

3. NSBlockOperation

   任務的操作執行在block中進行

   > [NSBlockOperation blockOperationWithBlock:^{

        …

    }]

 

4. NSOperationQueue 將任務添加到任務隊列中使其啟動執行

   > NSOperationQueue *que = [[NSOperationQueue alloc] init]  // 自訂隊列

   > que.name // 隊列名稱

   > que.maxConcurrentOperationCount  // 最大任務並發數,設定為1時為串列執行任務。預設是-1,表示沒有限制,會同時執行隊列中的任務。

   > [que addOperation:oper1]  // 將任務添加到隊列中以啟動執行

 

   除自訂隊列外:

   主隊列(該隊列中的任務在主線程執行):[NSOperationQueue mainQueue]

   當前隊列:[NSOperationQueue currentQueue]   

5. 任務間的依賴

   [oper1 addDependency:oper2] // 任務1依賴於任務2,任務1的執行必須等任務2執行完畢後才能開始

   注意此操作必須是在將任務添加到隊列前執行!!!

 

6. SDWebImage 圖片下載原理運用了NSOperation,NSOperationQueue

 

 

三、GCD============================================================

 

1. GCD:任務,隊列

   隊列分串列,並行隊列。

   串列隊列中的任務執行:GCD會FIFO(先進先出)的取出一個任務,執行一個後,再擷取下一個,依次類推。

   並行隊列中的任務執行:GCD也是按FIFO的方式取出任務,與串列的不同是:取出任務後會放倒別的線程上,然後再取出一個放到另外的線程....。 因為取任務的過程很快,看起來所有任務都是一起執行的。注意:GCD會根據系統資源控制並行的任務數量,任務太多時,不會讓所有任務同時執行。

 

2. 從程式上隊列分類:

   主隊列:(串列隊列)dispatch_queue_t qm = dispatch_get_main_queue();

   自訂隊列:(可串列,並行)dispatch_queue_t qself = dispatch_queue_create("myqueue", DISPATCH_QUEUE_CONCURRENT); // 通過第二個參數指定隊列是串列DISPATCH_QUEUE_SERIAL還是並行DISPATCH_QUEUE_CONCURRENT

   全域並行隊列:dispatch_queue_t qg = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

 

3. 隊列中添加要執行的任務(同步[阻塞當前線程],非同步任務[不阻塞當前線程])

    dispatch_async(qm, ^{

        // 在指定的隊列中要執行的任務...

    });

4. 隊列組

    多個隊列可以放到一個組中。

   // 建立隊列組 

   dispatch_group_t group = dispatch_group_create();

 

    dispatch_group_async(group, queue, ^{

        // 在指定的隊列組中,添加隊列queue, 並在queue中新增工作...

    });

    

    dispatch_group_notify(group, queue, ^{

        // 指定的組裡的所有任務完成後,發送通知給指定的隊列,並執行一個任務…,通常用於在主隊列中更新ui

    });

 

iOS多線程編程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.