IOS GCD的介紹及使用舉例&GCD優先級改變、after、group、barrier、sync、apply、semaphore、o

文章來源:http://blog.csdn.net/u011711753/article/details/24026275


目錄

一、GCD的隊列dispatch_queue_t

1、簡介

2、創建

1)、create方法
2)、get系統方法

3、修改create方法創建的隊列優先級

二、GCD的使用方法

1、使用步驟

2、代碼示例

三、GCD的其他方法

1dispatch_after-------------------------指定時間後追加

2、dispatch_group_t-----------------------處理組

3、dispatch_barrier_async-----------------queue中等待A執行後繼續queue中追加到其他

4、dispatch_sync--------------------------同步

5、dispatch_apply-------------------------指定次數的重複追加

6、dispatch_suspend&dispatch_resume-------暫停和繼續

7、dispatch_semaphore_t-------------------設置計數點

8、dispatch_once_t------------------------只執行一次



一、GCD的隊列dispatch_queue_t

1、簡介

dispatch_queue_t queue:執行處理的等待隊列可以將需要處理的代碼塊添加到這個隊列中


 

queue的分類:Serial順序 Concurrent並行

2、創建

有兩種方法,分別是create生成與get系統提供的


    1)create queue:

            dispatch_queue_create("", NULL)//第一個參數是queue的名字,第二個參數爲NULL表示Serial順序,這個只用於防止多對一的數據競爭時

            dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT)//第一個參數是queue的名字,第二個參數爲DISPATCH_QUEUE_CONCURRENT表示Concurrent並行

            dispatch_release(queue);//createqueue需要在結束使用後手動進行release

    

    2)系統queue:分爲Main主線程(也是一個Serial)和Global分線程(也是Concurrent)

            Main:dispatch_queue_t queue = dispatch_get_main_queue();

            Global://有四個優先級

                dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)//第一個參數爲優先級,這裏爲高優先級,第二個目前未使用,並且應該始終爲0

                dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)//第一個參數爲優先級,這裏爲默認優先級,第二個目前未使用,並且應該始終爲0

                dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)//第一個參數爲優先級,這裏爲低優先級,第二個目前未使用,並且應該始終爲0

                dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)//第一個參數爲優先級,這裏爲後臺優先級,第二個目前未使用,並且應該始終爲0


3、修改create方法創建的隊列優先級

    create創建的queue默認爲GlobalDEFAULT優先級,可以通過dispatch_set_target_queue(originQueue, targetQueue);//進行修改,第一個參數爲希望修改的queue,第二個參數爲修改後的目標queue,且第一個queue必須爲create創建的,不能使系統的Main或者Globalqueue。第二個queue應該是通過Global創建的某種優先級的queue

二、GCD的使用方法

1、使用步驟

    first:使用create或者系統方法創建一個queue

    second:使用dispatch_async(someQueue, ^{});執行多線程的block方法

    third:在上面多線程的block相應位置調用dispatch_async(dispatch_get_main_queue(), ^{});回到主線程進行操作

    fourth:如果queue時通過create創建的,使用dispatch_release(someQueue);進行釋放


2、代碼示例

    dispatch_queue_t tempQueue = dispatch_queue_create("com.llz.gcd.temp", NULL);

    dispatch_async(tempQueue,

                   ^{

                       //do something

                       dispatch_async(dispatch_get_main_queue(),

                                      ^{

                                         //do someting

                                      });

                   });

    dispatch_release(tempQueue);//因爲是create出來的,所以需要release


三、GCD的其他方法

1dispatch_after

    dispatch_after://在一個時間段後向某個queue中添加一個block方法


    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)3*NSEC_PER_SEC);//可以獲得一個距某個時間點相當時長的時間,第一個參數爲開始時間,現在設置的爲當前時間,第二個參數爲時間流失的數值,現在是3s

    dispatch_after(time, dispatch_get_main_queue(),

                   ^{

                       NSLog(@"hello");

                   });//使用dispatch_after方法,在time後向主線程隊列添加一個block方法

 

注意:dispatch_afterperformSelector:withObject:afterDelay:的區別,後者爲相應時間後執行該方法;前者爲相應時間後向隊列添加方法,而這個方法並不一定立刻執行

2、dispatch_group_t

    dispatch_group_t:多線程組,將一些queue,添加到這個中,可以實現監測這些queue全部完成的狀態,如果爲Serial就沒有使用這個的必要了

    

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//創建queue

    dispatch_group_t group = dispatch_group_create();//創建group

    

    dispatch_group_async(group, queue, ^{});//group中添加queue及其block方法,第一個參數爲組名,第二個參數爲queue名,第三個參數爲block方法

    dispatch_group_async(group, queue, ^{});//group中添加queue及其block方法

    dispatch_group_async(group, queue, ^{});//group中添加queue及其block方法

    dispatch_group_async(group, queue, ^{});//group中添加queue及其block方法

    

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);//可以通過wait方法設置監測時間,現在設置的是永遠,也能用dispatch_time_t進行特定時間的設定

    dispatch_release(group);//因爲是create出來的,所以需要release


3、dispatch_barrier_async

    dispatch_barrier_async(someQueue, ^{}):用於在某些一些動作中插入一些動作,一般配合create出來的concurrent類型queue使用,Serial就沒有使用這個的必要了

    

    dispatch_queue_t queue = dispatch_queue_create("", DISPATCH_QUEUE_CONCURRENT);

    

    dispatch_async(queue, ^{});

    dispatch_async(queue, ^{});

    dispatch_async(queue, ^{});

    dispatch_barrier_async(queue, ^{});//會將queue對應的block方法加入queue,並等此方法結束後再繼續queue裏的剩下block方法

    dispatch_async(queue, ^{});

    dispatch_async(queue, ^{});

    

    dispatch_release(queue);//因爲是create出來的,所以需要release


4、dispatch_sync


    dispatch_sync(someQueue, ^{})dispatch_barrier_sync(someQueue, ^{})同步運行,會死鎖,但是不要用在MainThread或者在非concurrent的本身queue裏面進行自己的sync

5、dispatch_apply

    dispatch_apply(10, someQueue, ^{}):用於將某個block代碼塊按指定次數重複追加到queue中,並等待這些block全部執行完畢,所以推薦用在async

    

    NSArray *array = [NSArray arrayWithObjects:@"",@"",@"",@"",@"",@"",@"", nil];

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_async(queue,

                   ^{

                       dispatch_apply(array.count, queue, ^(size_t index)//會將數組的長度作爲次數,將block代碼塊添加到queue中,並等待其中所有block執行完畢

                                      {

                                          NSLog(@"%@",[array objectAtIndex:index]);

                                      });

                   });


6、dispatch_suspend&dispatch_resume

    dispatch_suspend(someQueue)&dispatch_resume(someQueue):用於將掛起時queue中尚未執行的處理停止以及繼續開始

7、dispatch_semaphore_t

    dispatch_semaphore_t:計數信號,爲了更細分的保證不會造成程序的變量被同時訪問

    

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    

    dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);//初始化semaphore的計數,並設最大爲1

    NSMutableArray *array = [NSMutableArray arrayWithCapacity:0];

    

    for(int i = 0;i<10000;i++)//在循環中如果不用semaphore,則async出來的線程們可能會同時訪問array,造成異常

    {

        dispatch_async(queue,

                       ^{

                           dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//第一個參數爲技術信號,第二個參數爲等待時間,現在是一直等待直到semaphore的值等於1

                           

                           [array addObject:[NSNumber numberWithInt:i]];//排他成功後,即semaphore等於1時,執行數組添加對象操作,同時將semaphore值變爲0

                           

                           dispatch_semaphore_signal(semaphore);//semaphore的值增爲1

                       });

    }

    dispatch_release(semaphore);//因爲是create出來的,所以需要release


8、dispatch_once_t

    dispatch_once_t:保證其block塊在應用中只執行一次

        

    +(MyClass *)sharedInstance

    {

        static MyClass *sharedManager;

        

        static dispatch_once_t onceToken;//通過這個onceToken使得下面的實例化只做一次

        dispatch_once(&onceToken, ^{

            sharedManager = [[MyClass alloc] init];

        });

        

        return sharedManager;

    }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章