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"];
});
}
1次性代碼
#pragma mark - GCD 1次性代碼
- (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 (⑵) // 低
* 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);
//繪制第1張圖片
[image1 drawInRect:CGRectMake(0, 0, image1.size.width, image1.size.height)];
//繪制第2張圖片
[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(), ^{
// 等前面的異步操作都履行終了后,回到主線程...
});