iOS多線程開發之深入GCD

來源:互聯網
上載者:User

標籤:

iOS多線程開發之深入GCD 一、前言

        在以前的一些系列部落格中,對iOS中線程的管理做了總結,其中涵蓋了GCD的相關基礎知識:http://my.oschina.net/u/2340880/blog/417746。那裡面將GCD的線程管理能力,列隊組能力,通過訊號和訊息控製程序流程的能力都有介紹,這裡,我們繼續深入GCD的功能,通過GCD來處理一些邏輯更加複雜的代碼功能。

二、延時追加任務

        當我們在程式中處理延時任務的時候,我們一般會通過兩種方式,一種是通過定時器進行延時執行,另外一種是通過如下的函數:

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;

然而,如果我們需要在多線程中進行延時操作,上面兩種方式會顯得十分麻煩,並且徒增代碼的複雜度。GCD為我們提供了一種方式:

void  dispatch_after(dispatch_time_t when, dispatch_queue_t queue,  dispatch_block_t block);

這個方法有三個參數,第一個參數延時的時間,第二個參數為將任務加入的隊列,第三個block為要執行的任務。樣本如下:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{        NSLog(@"1233");    });

這裡通過dispatch_time來建立時間對象,將列印資訊的方法在3S後加入主線程隊列。需要注意的是,這裡只是將任務延時排入佇列,並不是執行,如果是加入同步隊列中,則會進入等待狀態。


三、資料存取的安全執行緒問題

        在進行多線程編程時,或許總會遇到一類問題,資料的競爭與線程的安全。這些問題如果我們通過程式手動來控制難度將會非常大。GCD同樣為我們簡單的解決了這樣的問題。

首先,如果只是在讀取資料,而不對資料做任何修改時,我們並不需要處理安全問題,可以讓多個任務同時進行讀取,可是如果要對資料進行寫的操作,那麼在同一時間,我們就必須只能有一個任務在寫,GCD中有一個方法幫我們完美的解決了這個問題,代碼如下:

//建立一個隊列dispatch_queue_t queue = dispatch_queue_create("oneQueue", DISPATCH_QUEUE_CONCURRENT);    //幾個任務同時讀操作    dispatch_async(queue, ^{        for (int i=0; i<5; i++) {            NSLog(@"read1:%d",i);        }    });    dispatch_async(queue, ^{        for (int i=0; i<5; i++) {            NSLog(@"read2:%d",i);        }    });    //此處進行寫操作    /*    下面這個函數在排入佇列時不會執行,會等待已經開始的非同步執行全部完成後再執行,並且在執行時,會阻塞其他任務    執行完成後,其他任務重新進入非同步執行    */        dispatch_barrier_async(queue, ^{        for (int i=0; i<5; i++) {            NSLog(@"write:%d",i);        }    });    //繼續進行非同步讀操作    dispatch_async(queue, ^{        for (int i=0; i<5; i++) {            NSLog(@"read3:%d",i);        }    });    dispatch_async(queue, ^{        for (int i=0; i<5; i++) {            NSLog(@"read4:%d",i);        }    });    dispatch_async(queue, ^{        for (int i=0; i<5; i++) {            NSLog(@"read5:%d",i);        }    });

列印資訊如下:


可以看出,讀操作是非同步進行的,寫操作是等待後阻塞任務隊列獨立進行,結束後隊列恢複非同步執行讀操作,這正是我們需要的效果。


四、GCD模式的單例

        通常情況下,我們的單例會是如下的樣子:

+(instancetype)shared{    static Auto * obj;    if (obj==nil) {        obj = [[Auto alloc]init];    }    return obj;}

這種通過讀取靜態變數的方式在大多數情況下是沒問題的,可是並不能保證程式百分百的安全,因為在多線程的操作中,會有可能初始化多個對象,在GCD中,我們可以使用如下方式:

+(instancetype)shared{    static Auto * obj;    //dispatch_once_t對象可以只保證執行一次    static dispatch_once_t once;    dispatch_once(&once, ^{        obj = [[Auto alloc]init];    });     return obj;    }


iOS多線程開發之深入GCD

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.