@interface ViewController (){
}
@property (nonatomic,strong) NSNumber *dataInt;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//NsThread
//[self threadDemo];
//GCD
//[self gcdDemo];
//
[self operationDemo];
}
-(void)operationDemo{
//Operation队列
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//设置最大的并发执行线程的数量
queue.maxConcurrentOperationCount = 4;
// 1.operation 1
//NSInvocationOperation 操作
// NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(updateUI2) object:nil];
// [operation start];
// 1.operation 2
NSBlockOperation *blockOper = [NSBlockOperation blockOperationWithBlock:^{
//这个也是更新UI的一种方式
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self updateUI];
}];
}];
//将NSBlockOperation添加到queue队列 ,添加到队列之后即将执行
[queue addOperation:blockOper];
// queue addOperations: NSOperation数组 waitUntilFinished:NO];
}
/**
* gcd DEMO
*/
-(void)gcdDemo{
//获取全局队列的方法 第一个参数是分配的一个处理事务的程序优先级 0为默认 2 为高,-2为低
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//线程异步
dispatch_async(queue, ^{
NSLog(@"线程异步");
//通知主线程刷新界面的第一种方式 子线程不能更新UI
dispatch_async(dispatch_get_main_queue(), ^{
});
//子线程更新UI的第二种方式
[self performSelectorOnMainThread:@selector(updateUI) withObject:self waitUntilDone:YES];
NSLog(@"%@",[NSThread currentThread]);
});
//线程同步 使用串行队列
queue = dispatch_queue_create("queue", 0);
//线程同步 第一个参数是指定一个gcd队列 第二个参数是分配一个处理事务的程序到该队列
dispatch_sync(queue, ^{
NSLog(@"线程同步");
});
}
-(void)updateUI{
//
NSLog(@"%@",[NSThread currentThread]);
UIImageView *image = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
image.image = [UIImage imageNamed:@"car.png"];
[self.view addSubview:image];
}
-(void)updateUI2{
//
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"%@",[NSThread currentThread]);
UIImageView *image = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
image.image = [UIImage imageNamed:@"car.png"];
[self.view addSubview:image];
});
}
/**
* //注意 NSThread的多个线程的执行顺序和生命周期是不可以控制的
*/
-(void)threadDemo{
//1.线程等待的代码
for (int i; i<1; i++) {
//这个是线程等待 单位是秒
[NSThread sleepForTimeInterval:1];
NSLog(@"%d",i);
}
_dataInt = [[NSNumber alloc]initWithInt:1];
// 2.创建线程的第一种方式
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(threadTest:) object:_dataInt];
[thread start];
_dataInt = [[NSNumber alloc]initWithInt:2];
// 3.创建线程的第二种方式 不需要start
[NSThread detachNewThreadSelector:@selector(threadTest:) toTarget:self withObject:_dataInt];
}
-(void)threadTest:(NSNumber *)dataInt{
NSLog(@"线程进来了%@",dataInt);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/**
*
1.NSThread 每个NSThread对象对应一个线程,量级较轻
2.NSOperation/NSOperationQueue 面向对象的线程技术
3.GCD —— Grand Central Dispatch 是基于C语言的框架,可以充分利用多核,是苹果推荐使用的多线程技术
以上这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。
NSThread:
优点:NSThread 比其他两个轻量级,使用简单
缺点:需要自己管理线程的生命周期、线程同步、加锁、睡眠以及唤醒等。线程同步对数据的加锁会有一定的系统开销
NSOperation:
不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上
NSOperation是面向对象的
GCD:
Grand Central Dispatch是由苹果开发的一个多核编程的解决方案。iOS4.0+才能使用,是替代NSThread, NSOperation的高效和强大的技术,GCD是基于C语言的
NSOperation的两个子类
NSInvocationOperation
NSBlockOperation
工作原理:
用NSOperation封装要执行的操作
将创建好的NSOperation对象放NSOperationQueue中
启动OperationQueue开始新的线程执行队列中的操作
注意事项:
使用多线程时通常需要控制线程的并发数,因为线程会消耗系统资源,同时运行的线程过多,系统会变慢
使用以下方法可以控制并发的线程数量:
(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
*/
@end