iOS開發之多線程

來源:互聯網
上載者:User

標籤:style   blog   http   io   color   ar   os   使用   java   

  在前面的部落格中如果用到了非同步請求的話,也是用到的第三方的東西,沒有正兒八經的用過iOS中多線程的東西。其實多線程的東西還是蠻重要的,如果對於之前學過作業系統的小夥伴來說,理解多線程的東西還是比較容易的,今天就做一個小的demo來詳細的瞭解一下iOS中的多線程的東西。可能下面的東西會比較枯燥,但還是比較實用的。

  多線程用的還是比較多的,廢話少說了,下面的兩張是今天我們實驗的最終結果,應該是比較全的,小夥伴們由圖來分析具體的功能吧:

  功能說明:

    1、點擊同步請求圖片,觀察整個UI介面的變化,並點擊測試按鈕,紅色是否會變成綠色。  

    2、NSThread按鈕,是由NSThread方式建立線程並執行相應的操作。

    3、Block操作按鈕是用Block建立操作,並在操作隊列中執行,下面的是Invocation操作

    4、serial是GCD中的串列隊列,concurrent是GCD中的並行隊列

  好啦,上面的鹹蛋先到這兒,代碼該走起啦。

  一、準備階段

     1.不管使用代碼寫,還是storyboard或者xib等,先把上面所需的控制項初始化好以便使用

     2.點擊測試UI按鈕,改變下邊label的顏色的代碼如下:

 1 //改變lable的顏色,在紅綠顏色之間進行交換 2 - (IBAction)tapTestButton:(id)sender { 3     static int i = 1; 4     if (i == 1) { 5         _testLabel.backgroundColor = [UIColor redColor]; 6         i = 0; 7     } 8     else 9     {10         _testLabel.backgroundColor = [UIColor greenColor];11         i = 1;12     }13     14 }

 

    3.從網路上擷取圖片,並使用主線程顯示進程調用情況

 1 //從wang‘lu擷取圖片資料 2 -(NSData *) getImageData 3 { 4      5     _count ++; 6     int count = _count; 7      8     NSData *data; 9     [NSThread sleepForTimeInterval:0.5];10     data = [NSData dataWithContentsOfURL:[NSURL URLWithString:IMAGEURL]];11 12     NSString *str = [NSString stringWithFormat:@"%d.線程%@完畢",count,[NSThread currentThread]];13     //請求資料的任務由其他線程解決,所以LogTextView的內容由主線程更新,也只有主線程才能更新UI14     [self performSelectorOnMainThread:@selector(updateTextViewWithString:) withObject:str waitUntilDone:YES];15     return data;16 }

 

    4.上面的用到了主線程來調用updateTextViewWithString方法,因為只有主線程才能更新UI,updateTextViewWithString:這個方法負責把線程的執行資訊顯示在View上,代碼如下:

1 //在ViewController上顯示圖片請求情況2 -(void)updateTextViewWithString:(NSString *)str3 {4     NSString *old_str = [NSString stringWithFormat:@"%@\n%@",_logTextView.text, str];5     6     _logTextView.text = old_str;7     //改變Label的顏色,便於觀察8     [self tapTestButton:nil];9 }

 

    5.把請求完的圖片載入到ImageView上

1 //更新圖片2 -(void) updateImageWithData:(NSData *)data3 {4     UIImage *image = [UIImage imageWithData:data];5     [_testImage setImage:image];6 }

 

    6.載入圖片的,也就是請求資料後在ImageView上顯示

1 //由其他線程請求資料,由主線程來更新UI2 -(void)loadImageWithThreadName:(NSString *)threadName3 {4     [[NSThread currentThread] setName:threadName];5     6     NSData *data = [self getImageData];7     [self performSelectorOnMainThread:@selector(updateImageWithData:) withObject:data waitUntilDone:YES];8 }

 

  二、通過各種方式來

    1.同步請求圖片測試,請求資料和更新UI都放在主線程中順序執行,這樣在請求資料的時候UI會卡死,代碼如下;

1 //同步請求圖片,視圖阻塞的,因為主線程被佔用,無法進行視圖的更新2 - (IBAction)tapButton:(id)sender {3     NSData *data = [self getImageData];4     [self updateImageWithData:data];5 }

 

    2.NSThread建立線程測試,用detachNewThreadSelector方法來建立新的線程會自動啟動並執行,而不用調用start方法。代碼如下:

1 //NSThread2 - (IBAction)tapButton2:(id)sender {3     //點擊一次button就建立一個新的線程來請求圖片資料4 5     [NSThread detachNewThreadSelector:@selector(loadImageWithThreadName:) toTarget:self withObject:@"NSThread"];6  }

   

    3.NSInvocationOperation的使用,建立一個叫用作業,然後添加到隊列中執行,代碼如下:

 1 //NSInvocationOperation 2 - (IBAction)tapInvocationOperation:(id)sender { 3     //執行個體化一個叫用作業,來執行資料請求 4     NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadImageWithThreadName:) object:@"Invocation"]; 5      6     //上面的叫用作業需要放到調用隊列裡才執行的 7     //建立操作隊列 8     NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init]; 9 10     //把上面的叫用作業放到操作隊列裡,隊列會自動開啟一個線程調用我們指定的方法11     [operationQueue addOperation:invocationOperation];12 }

 

    4.block的操作,建立一個block操作,並添加到隊列中執行,代碼如下:

 1 //BlockOperation 2 - (IBAction)tapBlockOperation:(id)sender { 3     __weak __block ViewController *copy_self = self; 4      5     //建立BlockOperation 6     NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ 7         [copy_self loadImageWithThreadName:@"Block"]; 8     }]; 9     10     //添加到操作隊列11     NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];12     [operationQueue addOperation:blockOperation];13     14     //另一種方式15     [operationQueue addOperationWithBlock:^{16         [copy_self loadImageWithThreadName:@"Block"];17     }];18     19 }

 

    5.GCD中的串列隊列:

 1 //串列隊列 2 - (IBAction)tapGCDserialQueue:(id)sender { 3     //建立串列隊列 4     dispatch_queue_t serialQueue = dispatch_queue_create("mySerialQueue", DISPATCH_QUEUE_SERIAL); 5      6      7     __weak __block ViewController *copy_self = self; 8     //非同步執行隊列 9     dispatch_async(serialQueue, ^{10         [copy_self loadImageWithThreadName:@"Serial"];11     });12     13 }

 

    6.GCD中的並行隊列:

 1 //並行隊列 2 - (IBAction)tapGCDConcurrentQueue:(id)sender { 3     //建立並行隊列 4     dispatch_queue_t concurrentQueue = dispatch_queue_create("myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT); 5     __weak __block ViewController *copy_self = self; 6     //非同步執行隊列 7     dispatch_async(concurrentQueue, ^{ 8         [copy_self loadImageWithThreadName:@"Concurrent"]; 9     });10 11 }

    以上是各個按鈕對應的方法,下面的是執行結果:

 

  三、線程間的同步問題(為我們的線程添加上同步鎖)

    在作業系統中講多線程時有一個名詞叫髒資料,就是多個線程操作同一塊資源造成的,下面就修改一下代碼,讓資料出現問題,然後用同步鎖來解決這個問題

    1.在getImageData方法(標題一中的第3個方法)中有兩條語句。這個用來顯示線程的標號。上面的標號是沒有重複的。

1     _count ++;2     int count = _count;

    在兩條語句中間加一個延遲,如下:

    _count ++;    [NSThread sleepForTimeInterval:1];    int count = _count;

    如果啟動並執行話,會有好多標號是重複的,一,__count是成員變數,多個線程對此他進行操作,所以會出現標號不一致的情況,下面我們加上同步鎖

     (1)用NSLock加同步鎖,代碼如下:

1     //通過NSLock加鎖2     [_lock lock];3     _count ++;4     [NSThread sleepForTimeInterval:1];5     int count = _count;6     [_lock unlock];

    (2)通過@synchronized加同步鎖,代碼如下:

1     //通過synchronized加鎖2     int count;3     @synchronized(self){4         _count ++;5         [NSThread sleepForTimeInterval:1];6          count = _count;7     }

      加鎖前後的運行效果如下:

  今天部落格中的內容還是蠻多的,如果之前接觸過Java的多線程的東西,或者其他語言中的多線程的話,理解起來應該問題不大。

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.