iOS中的多线程一般使用场景

在IOS开发中为提高程序的运行效率会将比较耗时的操作放在子线程中执行,iOS系统进程默认启动一个主线程,用来响应用户的手势操作以及UI刷新,因此主线程又叫做UI线程。
前面的Blog说明了NSThread以及GCD处理并发线程以及线程安全(线程锁@synchronized(){}),线程通信(从子线程向主线程传递值,刷新界面),接下来讨论线程的延迟与执行的单一化(唯一执行一次)。
1.延迟
(1)最简单粗暴的方法是对线程本身执行挂起操作
[NSThread sleepForTimeInterval:]
另外使用隐式创建开启线程的方法
self performSelector:withObject:afterDelay:
(2)使用GCD处理延迟操作(线程,任务)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
<#code to be executed after a specified delay#>
});
2.只执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
<#code to be executed once#>
});
3.为了方便管理任务队列中的任务,GCD特用分组的方式来管理
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async(group, queue, ^{
});
dispatch_group_notify(group, queue, ^{});
4.NSOperation与NSOperationQueue
为了对线程的操作更加的面向对象,APPLE对GCD进行了封装,特将任务—->封装成NSOperation
队列——>封装成NSOperationQueue
(1)NSOperation有两个子类NSInvocationOperation以及NSBlockOperation
NSInvocationOperation的创建方法如下:
// 创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 创建操作
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
// operation直接调用start,是同步执行(在当前线程执行操作)
// [operation start];

// 添加操作到队列中,会自动异步执行
[queue addOperation:operation];

(2)NSBlockOperation的创建方法:
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@”—下载图片—-11—%@”, [NSThread currentThread]);
}];

[operation1 addExecutionBlock:^{
    NSLog(@"---下载图片----12---%@", [NSThread currentThread]);
}];

NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"---下载图片----2---%@", [NSThread currentThread]);
}];

NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"---下载图片----3---%@", [NSThread currentThread]);
}];

NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"---下载图片----4---%@", [NSThread currentThread]);
}];

// 1.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 主队列

// NSOperationQueue *queue = [NSOperationQueue mainQueue];

// 2.添加操作到队列中(自动异步执行)
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];

其中NSOperation类可以添加执行代码块:addExecutionBlock
【NSOperationQueue mainQueue】是获取主队列,其实底层相当于dispatch_get_mainQueue()

NSBlockOperation *operation = [[NSBlockOperation alloc] init];

[operation addExecutionBlock:^{
    NSLog(@"---下载图片----1---%@", [NSThread currentThread]);
}];

[operation addExecutionBlock:^{
    NSLog(@"---下载图片----2---%@", [NSThread currentThread]);
}];

[operation addExecutionBlock:^{
    NSLog(@"---下载图片----3---%@", [NSThread currentThread]);
}];

[operation start];

// 任务数量 > 1,才会开始异步执行

5.线程的通信
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
// 1.异步下载图片
NSURL *url = [NSURL URLWithString:@”http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg“];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];

    // 2.回到主线程,显示图片

// [self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
// dispatch_async(dispatch_get_main_queue(), ^{
//
// });
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imageView.image = image;
}];
}];
控制Operation之间的运行顺序可以通过添加依赖来实现
- (void)dependency
{
/**
假设有A、B、C三个操作,要求:
1. 3个操作都异步执行
2. 操作C依赖于操作B
3. 操作B依赖于操作A
*/

// 1.创建一个队列(非主队列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 2.创建3个操作
NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"A1---%@", [NSThread currentThread]);
}];
//    [operationA addExecutionBlock:^{
//        NSLog(@"A2---%@", [NSThread currentThread]);
//    }];
//
//    [operationA setCompletionBlock:^{
//        NSLog(@"AAAAA---%@", [NSThread currentThread]);
//    }];

NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"B---%@", [NSThread currentThread]);
}];
NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"C---%@", [NSThread currentThread]);
}];

// 设置依赖
[operationB addDependency:operationA];
[operationC addDependency:operationB];

// 3.添加操作到队列中(自动异步执行任务)
[queue addOperation:operationC];
[queue addOperation:operationA];
[queue addOperation:operationB];

}

为了达到优化app性能的需求,有时候是需要控制并发线程的数目以及队列中的线程的运行状态
- (void)maxCount
{
// 1.创建一个队列(非主队列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

// 2.设置最大并发(最多同时并发执行3个任务)
queue.maxConcurrentOperationCount = 3;

// 3.添加操作到队列中(自动异步执行任务,并发)
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"下载图片1---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"下载图片2---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"下载图片3---%@", [NSThread currentThread]);
}];
NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"下载图片4---%@", [NSThread currentThread]);
}];
NSInvocationOperation *operation5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];

[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];
[queue addOperation:operation5];
[queue addOperationWithBlock:^{
    NSLog(@"下载图片5---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
    NSLog(@"下载图片6---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
    NSLog(@"下载图片7---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
    NSLog(@"下载图片8---%@", [NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
    NSLog(@"下载图片9---%@", [NSThread currentThread]);
}];

[queue cancelAllOperations];

}

  • (void)didReceiveMemoryWarning
    {
    [super didReceiveMemoryWarning];

// [queue cancelAllOperations]; // 取消队列中的所有任务(不可恢复)
}

  • (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
    // [queue setSuspended:YES]; // 暂停队列中的所有任务
    }

  • (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    {
    // [queue setSuspended:NO]; // 恢复队列中的所有任务
    }

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值