GCD
主要學習的知識點有:串行列隊,并行列隊,死鎖,group,柵欄
·串行列隊:A執行完,執行B,B執行完再執行C 排隊執行 SERIAL
·并行列隊:無序執行 CONCURRENT
·死鎖沒事少用同步方法,很容易造成主線程死鎖
·柵欄:AB可以無序執行,CD也可以無序執行,但是我們要AB執行完再執行CD,這樣我們就不好設置依賴關系了
·柵欄就可以擋在AB和CD的中間,等AB執行完了再執行CD
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
#if 0
// 主線程
dispatch_queue_t mainQueue = dispatch_get_main_queue();
// 子線程 異步執行
dispatch_queue_t subQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(subQueue, ^{
NSLog(@"task");
});
NSLog(@"hello");
#endif
#if 0
//異步執行
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (NSInteger i = 0; i<100; i++) {
dispatch_async(globalQueue, ^{
NSLog(@"i = %ld",i);
});
}
#endif
//自己創建一個新的線程
dispatch_queue_t customQueue = dispatch_queue_create("apple.queue",DISPATCH_QUEUE_CONCURRENT);
#if 0
dispatch_sync(customQueue, ^{
NSLog(@"task");
});
NSLog(@"hello");
#endif
#if 0
// 串聯列隊 有序執行打印 i = 0, i = 1, i = 2.... DISPATCH_QUEUE_SERIAL
customQueue = dispatch_queue_create("apple.queue2", DISPATCH_QUEUE_SERIAL);
customQueue = dispatch_get_main_queue();
for (NSInteger i = 0; i<100; i++) {
dispatch_async(customQueue, ^{
NSLog(@"i = %ld",i);
});
}
NSLog(@"hello world");
#endif
#if 0
NSLog(@"hello world");
//典型的死鎖 dispatch等待main打印"welcome",而打印這個方法是在主線程,造成死鎖
//主線程執行dispatch,dispatch又要用到主線程,進入一個死循環中,死鎖
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"welcome");
});
NSLog(@"======");
#endif
#if 0
//并聯列隊 無序執行,我們并不知道哪個先執行完 DISPATCH_QUEUE_CONCURRENT
dispatch_queue_t queue = dispatch_queue_create("apple.queu3", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"1");
});
dispatch_async(queue, ^{
NSLog(@"2");
});
dispatch_async(queue, ^{
NSLog(@"3");
});
NSLog(@"done");
#endif
#if 0
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("apple.queu3", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_async(group, queue, ^{
NSLog(@"1");
});
//group_notify不能放在最上面,group里為空時就會執行,放在group最上面的話就為空,其他group_async方法還沒有調用它就會先執行
//所有異步方法執行完后,打印"done"
dispatch_group_notify(group, queue, ^{
NSLog(@"done");
});
//異步方法中又有異步方法,比如網絡請求,group有可能不知道什么時候才執行notify
dispatch_group_async(group, queue, ^{
//所以我們設置一個標記,在開始這個異步方法前enter
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"2");
//執行完后leave
dispatch_group_leave(group);
});
});
dispatch_group_async(group, queue, ^{
NSLog(@"3");
});
dispatch_group_async(group, queue, ^{
NSLog(@"4");
});
dispatch_group_async(group, queue, ^{
NSLog(@"5");
});
#endif
dispatch_queue_t queue = dispatch_queue_create("apple.queu3",DISPATCH_QUEUE_CONCURRENT);
#if 0
//一個異步方法,比如說網絡下載
dispatch_async(queue, ^{
//下載data...
NSData *data;//....
//當我們要顯示時一定要在主線程里面執行
dispatch_async(dispatch_get_main_queue(), ^{
//主線程中顯示圖片
UIImage *image = [UIImage imageWithData:data];
});
});
#endif
#if 0
//1、2可以無序執行,3、4也可以無序執行,但是我們要1、2執行完再執行3、4. 這樣我們就不好設置依賴關系了
dispatch_async(queue, ^{
NSLog(@"1");
});
dispatch_async(queue, ^{
NSLog(@"2");
});
//柵欄就可以擋在1、2和3、4的中間,等1、2執行完了再執行3、4
dispatch_barrier_async(queue, ^{
NSLog(@"barrier");
});
dispatch_async(queue, ^{
NSLog(@"3");
});
dispatch_async(queue, ^{
NSLog(@"4");
});
#endif
}
@end