- 线程通讯
//获取全局队列
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//封装任务,将任务添加到队列中
dispatch_async(queue, ^{
NSLog(@"执行任务%@",[NSThread currentThread]);
//回到主线程刷新任务
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"刷新UI%@",[NSThread currentThread]);
});
});
//异步函数并不需要马上执行任务,不会阻塞线程。(先执行NSLog后再回头执行block里的任物)
NSLog(@"异步多线程");
- 一次性代码
//整个程序运行过程中,只会执行一次,开发实用场景:单例
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"一次性代码");
});
- 延迟执行
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), queue, ^{
NSLog(@"延迟执行%@",[NSThread currentThread]);
});
NSLog(@"异步多线程");
- 栅栏函数
//注意:栅栏函数不能使用全局并发队列
dispatch_queue_t queue = dispatch_queue_create("download", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"任务一-%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务二-%@",[NSThread currentThread]);
});
//栅栏函数
//栅栏函数之前队列中的任务执行完毕之后才会执行,栅栏函数之后之队列中的任务),但不阻塞线程是异步的
dispatch_barrier_async(queue, ^{
NSLog(@"我是栅栏函数");
});
NSLog(@"异步函数1");
dispatch_async(queue, ^{
NSLog(@"任务三-%@",[NSThread currentThread]);
});
NSLog(@"异步函数2");
```
- 队列组
```
//1.封装任务,将任务添加队列中,监听队列的执行情况
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_t group= dispatch_group_create();
//下载图片一
dispatch_group_async(group, queue, ^{
NSURL *url=[NSURL URLWithString:@"http://xo7788.com/uploads/allimg/160727/1130119505_0.jpg"];
NSData *imageData=[NSData dataWithContentsOfURL:url];
self.image1=[UIImage imageWithData:imageData];
//下载图片二
dispatch_group_async(group, queue, ^{
NSURL *url=[NSURL URLWithString:@"http://pic.58pic.com/58pic/17/41/38/88658PICNuP_1024.jpg"];
NSData *imageData=[NSData dataWithContentsOfURL:url];
self.image2=[UIImage imageWithData:imageData];
});
//下载图片三
dispatch_group_async(group, queue, ^{
NSURL *url=[NSURL URLWithString:@"http://pic.58pic.com/58pic/17/41/38/88658PICNuP_1024.jpg"];
NSData *imageData=[NSData dataWithContentsOfURL:url];
self.image2=[UIImage imageWithData:imageData];
});
//合并图片
//拦截通知,当队列组的所有任务完全,执行完后会进入下面的方法
//该方法本身是异步的
dispatch_group_notify(group, queue, ^{
//3.1 创建图形上下文
UIGraphicsBeginImageContext(CGSizeMake(200, 200));
//3.2 画图1
[self.image1 drawInRect:CGRectMake(0, 0, 200, 100)];
self.image1 = nil;
//3.3 画图2
[self.image2 drawInRect:CGRectMake(0, 100, 200, 100)];
self.image2 = nil;
//3.4 根据上下文得到一张图片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
//3.5 关闭上下文
UIGraphicsEndImageContext();
NSLog(@"%@合并",[NSThread currentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
self.imageview.image=image;
});
});
NSLog(@"异步函数");
```
- 多网络请求 (GCD信号量)
参考学习文章:http://www.jianshu.com/p/c194ca08776c
开发需求01:一个很常见的需求:项目中的业务接口请求的时候需要Token验证。我们最简化这个需求就是:两个请求,请求1成功返回所需参数之后,才能开始请求2。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//创建一个并行队列
dispatch_queue_t queque = dispatch_queue_create("GoyakodCreated", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queque, ^{
[self request1];
[self request2];
});
//注意这是请求不能放在主线程上,要不然,AFN的block回掉回造成线程死锁
}
-
(void)request1{
//01创建信号量并设置计数默认为0
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
//1.创建会话管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];//注意:如果返回的是xml数据,那么应该修改AFN的解析方案AFXMLParserResponseSerializer
//注意:如果返回的数据既不是xml也不是json那么应该修改解析方案为:
//manager.responseSerializer = [AFXMLParserResponseSerializer serializer];//告诉AFN能够接受text/html类型的数据
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//2.发送GET请求
[manager GET:@"http://www.baidu.com" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task,id _Nullable responseObject) {//02发送信号量计数+1 dispatch_semaphore_signal(sema); NSLog(@"网络请求1"); //UIImage *image = [UIImage imageWithData:responseObject]; NSLog(@"block-%@",[NSThread currentThread]);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
dispatch_semaphore_signal(sema);
NSLog(@"请求失败--%@",error);
}];//若计数为0则一直等待
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
-
(void)request2{
//1.创建会话管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //注意:如果返回的是xml数据,那么应该修改AFN的解析方案AFXMLParserResponseSerializer //注意:如果返回的数据既不是xml也不是json那么应该修改解析方案为: //manager.responseSerializer = [AFXMLParserResponseSerializer serializer]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //2.发送GET请求 [manager GET:@"http://120.25.226.186:32812/resources/images/minion_01.png" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task,id _Nullable responseObject) { NSLog(@"网络请求2"); //UIImage *image = [UIImage imageWithData:responseObject]; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { }];
}
开发需求02:两个网络请求后刷新界面
-
(void)viewDidLoad {
[super viewDidLoad];
// 创建信号量
semaphore = dispatch_semaphore_create(0);
// 创建全局并行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
// 请求一
[self request1];
NSLog(@"1");
});
dispatch_group_async(group, queue, ^{NSLog(@"2"); // 请求二 [self request2];
});
dispatch_group_notify(group, queue, ^{
// 2个请求对应2次信号等待
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"刷新界面");
});
}
-
(void)request1{
//1.创建会话管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];//注意:如果返回的是xml数据,那么应该修改AFN的解析方案AFXMLParserResponseSerializer
//注意:如果返回的数据既不是xml也不是json那么应该修改解析方案为:
//manager.responseSerializer = [AFXMLParserResponseSerializer serializer];//告诉AFN能够接受text/html类型的数据
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//2.发送GET请求
[manager GET:@"http://www.baidu.com" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task,id _Nullable responseObject) {//02发送信号量计数+1 dispatch_semaphore_signal(semaphore); NSLog(@"网络请求1"); //UIImage *image = [UIImage imageWithData:responseObject]; NSLog(@"block-%@",[NSThread currentThread]);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
dispatch_semaphore_signal(semaphore);
NSLog(@"请求失败--%@",error);
}];
}
-
(void)request2{
//1.创建会话管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //注意:如果返回的是xml数据,那么应该修改AFN的解析方案AFXMLParserResponseSerializer //注意:如果返回的数据既不是xml也不是json那么应该修改解析方案为: //manager.responseSerializer = [AFXMLParserResponseSerializer serializer]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //2.发送GET请求 [manager GET:@"http://120.25.226.186:32812/resources/images/minion_01.png" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task,id _Nullable responseObject) { NSLog(@"网络请求2"); dispatch_semaphore_signal(semaphore); //UIImage *image = [UIImage imageWithData:responseObject]; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { dispatch_semaphore_signal(semaphore); }];
}