程序员人生 网站导航

ios多线程 -- GCD 常见用法

栏目:综合技术时间:2016-08-04 09:14:40

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"]; }); }

延时操作
GCD延时操作

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(), ^{ // 等前面的异步操作都履行终了后,回到主线程... });
------分隔线----------------------------
------分隔线----------------------------

最新技术推荐