转自:http://www.maxiaoguo.com/clothes/254.html
多线程包括:GCD NSOperation NSOperation是在GCD语言的基础上开发的,GCD类C语言, NSOperation OC语法
GCD:
名词解释
并行 dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", DISPATCH_QUEUE_CONCURRENT); 串行 dispatch_queue_t q = dispatch_queue_create("cn.itcast.gcddemo", DISPATCH_QUEUE_SERIAL); 全局队列 dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 异步任务 dispatch_async(q, ^{ NSLog(@"异步任务 %@1111111", [NSThread currentThread]); }); 同步任务 dispatch_sync(q, ^{ NSLog(@"同步任务 %@1111111", [NSThread currentThread]); });
dispatch_queue_t q = dispatch_queue_create("cn.itcast.demoqueue", DISPATCH_QUEUE_CONCURRENT); dispatch_sync(q, ^{ NSLog(@"并行同步 %@", [NSThread currentThread]); });
主队列:
dispatch_queue_t q = dispatch_get_main_queue(); dispatch_async(q, ^{ NSLog(@"主队列异步 %@", [NSThread currentThread]); });容易发成死锁情况:
串行队列开启同步任务后嵌套同步任务造成死锁
串行队列开启异步任务后嵌套同步任务造成死锁
主队列不能放同步任务
NSOperation 中的 NSBlockOperation
用法:
n定义操作并添加到队列
self.myQueue = [[NSOperationQueue alloc] init];
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{ [self operationAction:@"BlockOperation"]; }]; n将操作添加到队列 [self.myQueue addOperation:op];这样的 NSBlockOperation是默认的异步的并行队列
// 设定执行顺序, Dependency依赖,可能会开多个,但不会太多 // 依赖关系是可以跨队列的! [op2 addDependency:op1]; [op3 addDependency:op2]; [op4 addDependency:op3]; // GCD是串行队列,异步任务,只会开一个线程
NSOperation 中的 NSInvocationOperation
// 需要定义一个方法,能够接收一个参数 // 是用起来不够灵活 NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(demoOp:) object:@"hello op"]; // [self.myQueue addOperation:op]; [[NSOperationQueue mainQueue] addOperation:op];
线程的资源抢夺:
解决方法: 加@synchronized
生成单例DemoObj的单例
+ (id)allocWithZone:(struct _NSZone *)zone { static DemoObj *instance; // dispatch_once是线程安全的,onceToken默认为0 static dispatch_once_t onceToken; // dispatch_once宏可以保证块代码中的指令只被执行一次 dispatch_once(&onceToken, ^{ // 在多线程环境下,永远只会被执行一次,instance只会被实例化一次 instance = [super allocWithZone:zone]; }); return instance; }错误写法,原因:当多个线程同时执行的时候会生成多个instance
+ (instancetype)sharedDemoObj { // 如果有两个线程同时实例化,很有可能创建出两个实例来 // if (!instance) { // // thread 1 0x0000A // // thread 2 0x0000B // instance = [[self alloc] init]; // } // // 第一个线程返回的指针已经被修改! // return instance; return [[self alloc] init]; }
NSThread
NSThread的创建主要有两种直接方式:
[NSThread detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self withObject:nil]; 和 NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:@selector(myThreadMainMethod:) object:nil]; [myThread start];