参考:https://www.jianshu.com/p/4b1d77054b35
只有异步开启子线程,在子线程中执行耗时任务才会避免阻碍主线程的UI界面
常用的方法如下:
//1.0 GCD 常用方式异步并发+与主线程交互
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//耗时长的操作
//子线程与主线程通信
dispatch_async(dispatch_get_main_queue(), ^{
//主线程界面刷新
});
});
//2.0 NSOperationQueue 常用方式异步并发+与主线程交互
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
//耗时长的操作
//子线程与主线程通信
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//主线程界面刷新
}];
}];
NSOperationQueue队列中可以同时执行多个任务,至于NSOperationQueue的取消暂停还没遇到实际的需求,暂缓待记~~~
//创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 5;//最大并发的任务数(并不一定是线程数,一个任务中可能多个线程)
NSArray *arr = @[@"a",@"b",@"c",@"d"];
NSBlockOperation *lastOp;
for (NSString *str in arr) {
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
NSData *data;
data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://www.baidu.com"]];
[self.mArr addObject:str];
// [NSThread sleepForTimeInterval:2.0];
LOG(@"~~~任务%@:%@ %@~~~%@",str,data,self.mArr,[NSThread currentThread]);
}];
//添加依赖
if (lastOp) {
[op addDependency:lastOp];
lastOp = op;
}else{
lastOp = op;
}
[queue addOperation:op];
}
[queue waitUntilAllOperationsAreFinished];//等待所有的任务结束,这个会阻塞当前的线程
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
UILabel *label= [self.view viewWithTag:100];
label.text = [NSString stringWithFormat:@"任务结束%@",self.mArr];
LOG(@"~~~任务结束:%@~~~%@",self.mArr,[NSThread currentThread]);
}];
实际的af网络请求也是个异步的操作,此时需要的是实际数据的接受完成再去重新刷新UI,这时候可以借助信号量,将AF的异步请求强制处理成同步,这时候达到的效果:异步串行
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 5;//最大并发的任务数(并不一定是线程数,一个任务中可能多个线程)
NSArray *arr = @[@"eth",@"btc",@"bts",@"nas",@"ltc"];
NSBlockOperation *lastOp;
for (NSString *str in arr) {
/*任务a */
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
//创建信号量
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[self getDepositNoticeWithAssetCode:str LeaveBlock:^{
//信号量+1
dispatch_semaphore_signal(sema);
}];
//当前线程根据信号量的值在等待(信号量值为0在等待,否则往下执行并且减去1)
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}];
//添加依赖
if (lastOp) {
[op addDependency:lastOp];
lastOp = op;
}else{
lastOp = op;
}
[queue addOperation:op];
if ([str isEqualToString:arr.lastObject]) {
NSBlockOperation *endOp = [NSBlockOperation blockOperationWithBlock:^{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
LOG(@"~~~任务abcd执行完成~~~");
}];
}];
[endOp addDependency:op];
[queue addOperation:endOp];
}
}
//加信号量这里线程已经阻塞,不会执行(可以放开测试)
// [queue waitUntilAllOperationsAreFinished];//等待所有的任务结束,这个会阻塞当前的线程
LOG(@"~~~我就是想看看会不会阻塞当前的线程~~~");
网友评论