[IOS 開發] GCD常用方法
阿新 • • 發佈:2019-02-02
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");
});