1. 程式人生 > >[IOS 開發] GCD常用方法

[IOS 開發] GCD常用方法

1:dispatch_source_t

    //dispatch_source_t 預設是掛起的,需要dispatch_resume()
    //這個和子執行緒處理資料主執行緒更新介面的優點在於,當主執行緒比較空閒一起更新介面.效率更高
    dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());
    
    dispatch_source_set_event_handler(source, ^{
        NSLog(@"%ld",dispatch_source_get_data(source));
    });
    
    dispatch_resume(source);
    
    dispatch_apply(100, dispatch_get_global_queue(0, 0), ^(size_t index) {
        // do some work on data at index
        dispatch_source_merge_data(source, 1);
    });

2:GCD定時器

//    dispatch_suspend(dispatch_object_t object);  //暫停執行緒
//    dispatch_resume(dispatch_object_t object);   //恢復執行緒
//    dispatch_source_set_timer(dispatch_source_t source,   //timer
//                              dispatch_time_t start,      //dispatch_time(開始時間,延遲多少秒)
//                              uint64_t interval,          //間隔時間
//                              uint64_t leeway);           //可以誤差時間
    
    __block int timeout = 30; //倒計時時間
    
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,  dispatch_get_main_queue());
    
    dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, 0ull*NSEC_PER_SEC), 1ull*NSEC_PER_SEC, 2ull*NSEC_PER_SEC);
    
    dispatch_source_set_event_handler(timer, ^{
        
        if(timeout == 0) //倒計時結束,關閉
        {
            NSLog(@"結束");
            dispatch_source_cancel(timer);        //沒有dispatch_source_cancel()方法,timer不會執行
//          dispatch_suspend(timer);
        }
        else
        {
            NSLog(@" == %@, == %@",[NSString stringWithFormat:@"%.2d", timeout--],[NSDate new]);
        }
    });
    
    dispatch_source_set_cancel_handler(timer, ^{
        NSLog(@"cancel");
    });
    
    //啟動
    dispatch_resume(timer);

3:group,GCD編組的功能
dispatch_group_t group = dispatch_group_create();dispatch_group_wait(group, DISPATCH_TIME_NOW);
    dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
        NSLog(@"============1");
    });
    dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
        sleep(10);
        NSLog(@"============2");
    });
    
    //保證dispatch_group_notify是最後輸出
    dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
        NSLog(@"============3");
    });
    
    dispatch_queue_t aDQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
    dispatch_group_t group1 = dispatch_group_create();
    
    dispatch_queue_t aDQueue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_group_t group2 = dispatch_group_create();
    
    // Add a task to the group
    dispatch_group_async(group1, aDQueue, ^{
        printf("task 1 \n");
    });
    dispatch_group_async(group1, aDQueue, ^{
        printf("task 2 \n");
    });
    dispatch_group_async(group1, aDQueue, ^{
        printf("task 3 \n");
    });
    dispatch_group_wait(group1, DISPATCH_TIME_FOREVER);
    printf("task 1 2 3 finished \n");
    
    
    dispatch_group_async(group2, aDQueue2, ^{
        printf("task2 1 \n");
    });
    dispatch_group_async(group2, aDQueue2, ^{
        printf("task2 2 \n");
    });
    dispatch_group_async(group2, aDQueue2, ^{
        printf("task2 3 \n");
    });
    dispatch_group_wait(group2, DISPATCH_TIME_FOREVER);
    printf("task2 1 2 3 finished \n");

4:使用者自定義佇列

    //佇列之間的依賴關係
    //使用者佇列最主要的功能就是安排 執行緒之間的執行順序.
    dispatch_queue_t targetQueue = dispatch_queue_create("test.target.queue", DISPATCH_QUEUE_SERIAL);
    
    dispatch_queue_t queue1 = dispatch_queue_create("test.1", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue2 = dispatch_queue_create("test.2", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue3 = dispatch_queue_create("test.3", DISPATCH_QUEUE_SERIAL);
    
    dispatch_set_target_queue(queue1, targetQueue);
    dispatch_set_target_queue(queue2, targetQueue);
    dispatch_set_target_queue(queue3, targetQueue);
    
    
    dispatch_async(queue1, ^{
        NSLog(@"1 in");
        [NSThread sleepForTimeInterval:3.f];
        NSLog(@"1 out");
    });
    
    dispatch_async(queue2, ^{
        NSLog(@"2 in");
        [NSThread sleepForTimeInterval:2.f];
        NSLog(@"2 out");
    });
    
    dispatch_async(queue3, ^{
        NSLog(@"3 in");
        [NSThread sleepForTimeInterval:1.f];
        NSLog(@"3 out");
    });

5:訊號量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(6);   //括號中填幾,就可以有幾個任務同時並行.
    
    for (int i = 0; i < 100; i++)
    {
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
            
            sleep(2);
            
            NSLog(@"index = %d",i);
            
            //通知訊號量,semaphore的value會自動加1.
            dispatch_semaphore_signal(semaphore);
    
            //下面是semaphore的資料.value是訊號量當前的值.orig是建立的時候有多少值.
            //{ xrefcnt = 0x1, refcnt = 0x1, suspend_cnt = 0x0, locked = 0, port = 0x0, value = 2, orig = 3 }

        });
    }

6:dispatch_barrier_async
//    作用是在並行佇列中,等待前面兩個操作並行操作完成,再執行後面的輸出
    dispatch_queue_t queue6 =dispatch_queue_create("gcdtest.zfl.demo",DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue6, ^{
        
        [NSThread sleepForTimeInterval:2];
        
        NSLog(@"dispatch_async1");
        
    });
    
    dispatch_async(queue6, ^{
        
        NSLog(@"dispatch_async2");
        
    });
    
    dispatch_barrier_async(queue6, ^{
        
        NSLog(@"dispatch_barrier_async");
        
    });
    
    dispatch_async(queue6, ^{
        
        NSLog(@"dispatch_async3");
        
    });

7:dispatch_after
//延遲2.0s執行
    
    int64_t delayInSeconds = 2.0;
    
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW,delayInSeconds * NSEC_PER_SEC);
    
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        
        //do something...
        


8:dispatch_queue_create

 

    DISPATCH_QUEUE_SERIAL

    //NULL預設的是 DISPATCH_QUEUE_SERIAL
    NSLog(@"=====Concurrent Diapatch Queue 併發佇列,一個佇列觸發多個執行緒=====");

    //建立併發佇列  
    dispatch_queue_t concurrentDiapatchQueue=dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);  
    //使用佇列  
    dispatch_async(concurrentDiapatchQueue, ^{  
        NSLog(@"1");  
    });  
    dispatch_async(concurrentDiapatchQueue, ^{  
        sleep(2);  
        NSLog(@"2");  
    });  
    dispatch_async(concurrentDiapatchQueue, ^{  
        sleep(1);  
        NSLog(@"3");  
    });  
   
    DISPATCH_QUEUE_CONCURRENT

    NSLog(@"=====Concurrent Diapatch Queue 併發佇列,一個佇列觸發多個執行緒=====");

    //建立併發佇列  
    dispatch_queue_t concurrentDiapatchQueue=dispatch_queue_create("com.test.queue", DISPATCH_QUEUE_CONCURRENT);  
    //使用佇列  
    dispatch_async(concurrentDiapatchQueue, ^{  
        NSLog(@"1");  
    });  
    dispatch_async(concurrentDiapatchQueue, ^{  
        sleep(2);  
        NSLog(@"2");  
    });  
    dispatch_async(concurrentDiapatchQueue, ^{  
        sleep(1);  
        NSLog(@"3");  
    });