標籤:
GCD 通訊操作
#pragma mark - GCD 通訊- (void)sendMessage{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //耗時操作 [self downLoad:@"http://..."]; //回主隊列重新整理資料 dispatch_async(dispatch_get_main_queue(), ^{ //重新整理UI操作 }); });}
延時操作
iOS常見的延時執行有2種方式
(1)調用NSObject的方法
// 2秒後再調用self的run方法[self performSelector:@selector(run) withObject:nil afterDelay:2.0];
(2)使用GCD函數
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // 2秒後非同步執行這裡的代碼...});
代碼示範:
#pragma mark - GCD 延遲- (void)delayModel:(CGFloat)time{ // 經過延遲 time 秒後,回到當前線程,執行。不會卡住當前線程 // 該方法在那個線程調用,那麼run就在哪個線程執行(當前線程),通常是主線程 //[self performSelector:@selector(downLoad:) withObject:@"delayModel" afterDelay:time]; // GCD 實現 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(time * NSEC_PER_SEC)), queue, ^{ [self downLoad:@"GCD---delayModel"]; });}
一次性代碼
#pragma mark - GCD 一次性代碼- (void)onceCore{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // 只執行1次的代碼(這裡面預設是安全執行緒的) [self downLoad:@"onceCore"]; });}
隊列組
#pragma mark - GCD 隊列組- (void)groupQueue{ // 1 擷取全域隊列 /** * 優先順序 * DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高 * DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 預設(中) * DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低 * DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 後台 */ dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 2 擷取隊列組 dispatch_group_t group = dispatch_group_create(); // 3 下載圖片1 //__block 修飾的值才能在 block 中改 __block UIImage *image1 = nil; dispatch_group_async(group, queue, ^{ //下載圖片 NSString *urlStr = @"http://b.hiphotos.baidu.com/image/pic/item/cdbf6c81800a19d8c58c800431fa828ba61e4627.jpg"; NSURL *url = [NSURL URLWithString:urlStr]; NSData *data = [NSData dataWithContentsOfURL:url]; image1 = [UIImage imageWithData:data]; }); // 4 下載圖片2 __block UIImage *image2 = nil; dispatch_group_async(group, queue, ^{ //下載圖片 NSString *urlStr = @"http://b.hiphotos.baidu.com/image/w%3D230/sign=fbc72e14362ac65c67056170cbf2b21d/e4dde71190ef76c666af095f9e16fdfaaf516741.jpg"; NSURL *url = [NSURL URLWithString:urlStr]; NSData *data = [NSData dataWithContentsOfURL:url]; image2 = [UIImage imageWithData:data]; }); // 5 合并圖片1, 2 dispatch_group_notify(group, queue, ^{ //擷取圖形上下文 UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0); //繪製第一張圖片 [image1 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)]; //繪製第二張圖片 [image2 drawInRect:CGRectMake(0, 0, image2.size.width * 4, image2.size.height * 3)]; //得到內容相關的新圖片 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); //關閉上下文 UIGraphicsEndImageContext(); //回到主線程重新整理介面 dispatch_async(dispatch_get_main_queue(), ^{ self.imageView.image = newImage; }); });}
補充:
有這麼1種需求:首先:分別非同步執行2個耗時的操作其次:等2個非同步作業都執行完畢後,再回到主線程執行操作如果想要快速高效地實現上述需求,可以考慮用隊列組dispatch_group_t group = dispatch_group_create();dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 執行1個耗時的非同步作業});dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 執行1個耗時的非同步作業});dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // 等前面的非同步作業都執行完畢後,回到主線程...});
ios多線程 -- GCD 常見用法