多線程編程(一)NSThread

     在iOS中每一個進程啓動後都會創建一個主線程(UI線程),這個線程是其餘線程的父線程。因爲在iOS中除了主線程,其餘子線程是獨立於Cocoa Touch的,因此只有主線程能夠更新UI界面(新版iOS中,使用其餘線程更新UI可能也能成功,可是不推薦)。iOS中多線程使用並不複雜,關鍵是如何控制好各個線程的執行順序、處理好資源競爭問題。 安全

   多線程開發中,須要明白一點,cpu在同一時間內,只能處理一件事情,多線程開發,只是cpu在各個線程之間來回穿梭調度,並非cpu可以同時執行多個任務,這一須要明確,本篇博客主要講一下NSThread服務器

 一   NSThread的建立有三種方式多線程

    //第一種  先建立 再啓動  注意 object參數 若是down方法須要參數 就在object這裏把參數傳遞給down方法spa

    NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(down) object:nil];線程

    [thread start];orm

     //第二種 建立 不用啓動對象

    [self performSelectorInBackground:@selector(down) withObject:nil];進程

    //第三種 建立 不用啓動圖片

    [NSThread detachNewThreadSelector:@selector(down) toTarget:self withObject:nil];資源

把比較耗時的操做放在down方法中,可是不要把UI的更新放在down方法中。

 取消線程  [thread cancel];線程執行完操做後 會自動銷燬,也就是說 一個線程只能處理一個任務

 

二  線程之間的通訊 ,好比在子線程中下載一張圖片,下載完要回到主線程刷新UI;

    [self performSelectorOnMainThread:@selector(update:) withObject:img waitUntilDone:YES];

這句代碼中的withObject:後面的參數img就是下載的圖片,而後在update:方法中 給imgView賦值,

這句代碼還有一種表達方式

    [self performSelector:@selector(update:) onThread:[NSThread mainThread] withObject:img waitUntilDone:YES];

 其實這裏還有一種比較簡單的方法 不用寫update方法了 既然給imgView賦值  直接這樣寫

    [self.myImgView performSelector:@selector(setImage:) onThread:[NSThread  mainThread] withObject:img waitUntilDone:YES];

 三 線程間的安全問題

若是咱們的多個線程對同一個資源同時訪問,可能就會產生問題,好比咱們的賣票問題,好比開了三個線程賣票,共有10張票,線程一訪問時是10張,當線程一訪問完後,線程二又立刻來訪問,線程二訪問時仍是10張,線程二訪問完後,線程一賣了一張票,此時線程一返回給服務器的值是10-1 = 9張票,此時線程二也賣了一張,線程二返回的確定也是10-1=9張,這樣確定是有問題的,爲了不這種狀況,此時咱們要爲共同訪問的資源加鎖,仍是直接上代碼。

    self.thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];

    self.thread1.name = @"窗口1";

    self.thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];

    self.thread2.name = @"窗口2";

    self.thread3 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];

    self.thread3.name = @"窗口3";

    [self.thread1 start];

    [self.thread2 start];

    [self.thread3 start];

 

        @synchronized(self){

          int count = self.leftTicketCount;

           if (count > 0) {

              self.leftTicketCount = count - 1;

              NSLog(@"%@賣了1張票,還剩%d張票",[NSThread currentThread].name,self.leftTicketCount);

            }else{

             return;

            }

        }

 其實@synchronized()就是加鎖,後面小括號裏面就是鎖對象, 鎖對象的能夠是任意的對象,能夠直接用self,注意 鎖要用一個 不能每次建立一個 那樣和沒加鎖是同樣的效果,

 NSThread的大致用法就這些,如今已經不是太經常使用NSThread 了 主要是用GCD 和NSOperation 另外還有一種Pthread  幾乎不用,有興趣的能夠了解下,GCD和NSOperation會在後面的章節寫下,哪裏有不對的地方,歡迎你們評批指正。

相關文章
相關標籤/搜索