[iOS]Block(一) Block與GCD多執行緒運用

  • 2417
  • 0
  • iOS
  • 2015-04-02

摘要:[iOS]Block與GCD多執行緒運用(一)

如果有寫過.Net windows Form的應用程式,你就會有經驗,在Form程式裡面的UI控制項都是跑在主要的執行緒中。如果要避免當你執行某些動作時,為了解決UI控制項回應時照成的等待,常常會使用到多執行續來處理。而當我們在其他執行緒處理的動作要更新到UI控制項的狀態,就需要呼叫主執行緒裡面的物件來做更新的動作。在.Net裡面會用下列的語法來處理這段。

this.InvokeOnMainThread(() =>{
    dosomething ;             
});

在iOS的結構上,基本概念是一樣的。只要是跟視覺化有關係的UI控制項,都是執行在主要執行緒。

iOS在多執行緒的處理提供了兩種方式,傳統的NSThread與Grand Center Dispatch。這邊我會用GCD的佇列方式來處理這個範例。

建立一個iOS專案,在View裡面拖拉一個Progress bar。我們要利用這個Progress bar來模擬網路下載資料時的完成度百分比呈現。

在ViewController.h檔案拖拉建立Progress Bar的IBOutlet關聯。接著在宣告一個方法dosomething。

ViewController.h

#import 
@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UIProgressView *myProgress;
-(void)dosomething;
@end

 

把畫面切到ViewController.m檔案,在這裏先來實作dosomething這個函數的內容。在這個內容之中,我們跑一個迴圈,並且在每次進入這個迴圈的時候,停止一秒鐘,接著去更新iOS畫面上的UI元件,呈現出Progress bar在讀取進度的效果。而在dosomething這個函數要去更新主執行緒中的UI元件狀態時,我們需要去呼叫Main queue來更新元件。

回到ViewDidLoad方法中,在這裡建立一個serial queue。接著執行dispatch_async。在block區域中呼叫dosomething方法。

#import "ViewController.h"
@interface ViewController ()
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
     self.myProgress.progress = 0;
    //自訂serial queue
    dispatch_queue_t myQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
   //用非同步的方式執行
    dispatch_async(myQueue,^{
        [self dosomething];
    });
    NSLog(@"主執行緒結束");
}

-(void)dosomething{    
    int i;
    for (i=0; i<= 10; i+=1) {
        [NSThread sleepForTimeInterval:1.0f];
        //更新主執行緒上的UI控制項
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.myProgress setProgress:i*0.1];
        });
        NSLog(@"%d",i);
    }
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

執行這個App,可以看到模擬器上產生了進度條讀取的效果。

 

範例檔案下載位置:https://github.com/twbenlu/iOSGCDandBlock