NSOperation :
1.–不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上
2.–NSOperation是面向对象的
工作原理:
1.用NSOperation封装要执行的操作
2.将创建好的NSOperation对象放NSOperationQueue中
3.启动OperationQueue开始新的线程执行队列中的操作
注意事项:
1.使用多线程时通常需要控制线程的并发数,因为线程会消耗系统资源,同时运行的线程过多,系统会变慢
2.使用以下方法可以控制并发的线程数量:
-(void)setMaxConcurrentOperationCount:(NSInteger)count;
NSInvocationOperation *iop1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(eat) object:nil];
NSInvocationOperation *iop2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(drink) object:nil];
//依赖关系,iop1依赖于iop2,那么就是一定在iop2执行完成后再执行iop1
[iop1 addDependency:iop2];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//waitUntilFinished是否等待队列中的任务执行完后再去执行后面的代码
[queue addOperations:@[iop1,iop2] waitUntilFinished:NO];
//挂起主线程,等待所有的任务都完成,主线程才能继续
//[queue waitUntilAllOperationsAreFinished];
NSBlockOperation *bop = [NSBlockOperation blockOperationWithBlock:^{
[self eat];
}];
[bop addExecutionBlock:^{
[self drink];
}];
bop.completionBlock = ^{
NSLog(@"吃完喝完");
};
[bop start];
GCD :
1.–Grand Central Dispatch(大规模分发中心)是由苹果开发的一个多核编程的解决方案。iOS4.0+才能使用,是替代NSThread, NSOperation的高效和强大的技术
2.–GCD是基于C语言的
优点:
1.充分利用多核
2.所有的多线程代码集中在一起,便于维护
3.GCD中无需使用@autoreleasepool
4.如果要顺序执行,可以使用dispatch_sync同步方法
5.dispatch_async无法确定任务的执行顺序
GCD创建多任务
//创建一个异步任务
//获取全局queue, 全局queue添加任务之后默认异步执行
//以后获取mainQueue--对应主线程
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//异步执行一个任务
dispatch_async(queue, ^{
for (int i=0; i<100; i++)
{
NSLog(@"A i=%d",i);
[NSThread sleepForTimeInterval:0.1];
}
});
dispatch_async(queue, ^{
for (int i=0; i<100; i++)
{
NSLog(@"B i=%d",i);
[NSThread sleepForTimeInterval:0.1];
}
});
GCD实现异步下载,模仿SDWebImage工程
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[self.view addSubview:imageView];
//异步使用GCD加载图片
//原理: 开启新的线程下载数据, 下载完成后更新UI
//开启了一个异步任务
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//下载文件
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://img0.bdstatic.com/img/image/shouye/gxdw-11711533352.jpg"]];
UIImage *image = [[UIImage alloc] initWithData:data];
//图片更新到UI中
NSLog(@"w:%f h:%f",image.size.width,image.size.height);
//GCD子任务中更新UI,不能直接更新
//获取UI主线程queue, 通过queue更新
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = image;
});
});
GCD实现一些代码只会执行一次,(单例)
//需求: 有句程序中只会执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"我是代码, 被执行了~_~");
});
GCD延迟执行
//使用 dispatch_after
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
NSLog(@"a code run .....");
});
队列执行
//创建一个任务组
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"任务A完成");
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"任务B完成");
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"任务C完成");
});
//需求: 当所有任务完成后做出处理
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"所有任务完成之后执行");
});