GCD
是iOS多线程实现方案之一,非常常用
英文翻译过来就是伟大的中枢调度器,也有人戏称为是牛逼的中枢调度器
是苹果公司为多核的并行运算提出的解决方案
1.一次性函数
dispatch_once
顾名思义是只执行一次的函数,注意是整个程序中只执行一次(单例模式常用到)
- (void)once { //一次性函数,只执行函数 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ //里面默认线程安全的 NSLog(@"------run"); }); }
2.栅栏函数
dispatch_barrier_async
作用就是控制多线程的执行顺序
- (void)barrier { dispatch_queue_t queue = dispatch_queue_create("123", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ NSLog(@"_______1--------%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"_______2--------%@",[NSThread currentThread]); }); //像栅栏一样,让上面的先执行完,再执行下面的 dispatch_barrier_async(queue, ^{ NSLog(@"----barrier-----%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"_______3--------%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"_______4--------%@",[NSThread currentThread]); }); }
3.快速迭代函数
dispatch_apply
作用就是开启多个线程同时完成某一件事,例如同时下载多张图片
//一般的做法 - (void)cutFromFileTo { //一般在子线程中做 //创建并行队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ //起始路径 NSString *from = @"/Users/DDZ/Desktop/From"; //目标路径 NSString *to = @"/Users/DDZ/Desktop/To"; NSFileManager *mgr = [NSFileManager defaultManager]; //获取起始路径中所有文件路径 NSArray *subpaths = [mgr subpathsAtPath:from]; for (int i = 0; i < subpaths.count; i++) { //将路径字符串进行拼接 NSString *fromFullPath = [NSString stringWithFormat:@"%@/%@",from,subpaths[i]]; NSString *toFullPath = [NSString stringWithFormat:@"%@/%@",to,subpaths[i]]; [mgr moveItemAtPath:fromFullPath toPath:toFullPath error:nil]; } NSLog(@"剪切成功"); }); }
//使用快速迭代进行剪切 - (void)cutFileApply { //起始路径 NSString *from = @"/Users/DDZ/Desktop/From"; //目标路径 NSString *to = @"/Users/DDZ/Desktop/To"; NSFileManager *mgr = [NSFileManager defaultManager]; //获取起始路径中所有文件路径 NSArray *subpaths = [mgr subpathsAtPath:from]; dispatch_apply(subpaths.count, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) { NSString *subpath = subpaths[index]; //将路径字符串进行拼接 NSString *fromFullPath = [NSString stringWithFormat:@"%@/%@",from,subpath]; NSString *toFullPath = [NSString stringWithFormat:@"%@/%@",to,subpath]; //剪切 [mgr moveItemAtPath:fromFullPath toPath:toFullPath error:nil]; }); }
一般的方法只能一张图片剪切完之后,再进行下一张得剪切
而使用快速迭代则可以同时进行剪切。
4.队列组
dispatch_group_async
与栅栏函数有相同的目的,为了控制多线程的执行顺序
例如下载两张图片之后,再将这两者合并成新的图片并显示。
必须得先下完之后才能合并吧!(顺序问题,多线程是不可控的)
//队列组 - (void)group { //创建组 dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //1.下载图片1 dispatch_group_async(group, queue, ^{ //实现下载 NSURL *url = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/6c224f4a20a446230761b9b79c22720e0df3d7bf.jpg"]; NSData *data = [NSData dataWithContentsOfURL:url]; //生成图片 self.img1 = [UIImage imageWithData:data]; }); //2.下载图片2 dispatch_group_async(group, queue, ^{ //实现下载 NSURL *url = [NSURL URLWithString:@"http://h.hiphotos.baidu.com/image/pic/item/b812c8fcc3cec3fd5b9db074d488d43f8794270b.jpg"]; NSData *data = [NSData dataWithContentsOfURL:url]; self.img2 = [UIImage imageWithData:data]; }); //3.将图片1,图片2合成一张新的图片 dispatch_group_notify(group, queue, ^{ //开启新的图形上下文 UIGraphicsBeginImageContext(CGSizeMake(200, 200)); //绘制图片 [self.img1 drawInRect:CGRectMake(0, 0, 100, 200)]; [self.img2 drawInRect:CGRectMake(100, 0, 100, 200)]; //取得上下文中的图片 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); //结束上下文 UIGraphicsEndImageContext(); //回到主线程显示图片 dispatch_async(dispatch_get_main_queue(), ^{ //4.将新图片显示出来 self.imageView.image = image; }); }); }
5.延时(补充)
- (void)delay { //延时 NSLog(@"______"); [self performSelector:@selector(run) withObject:nil afterDelay:2.0]; } - (void)run { NSLog(@"end"); }
时间: 2024-11-13 14:11:51