ios 多线程

转自: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]); });

easy发成死锁情况:

串行队列开启同步任务后嵌套同步任务造成死锁

 串行队列开启异步任务后嵌套同步任务造成死锁

主队列不能放同步任务

NSOperation 中的 NSBlockOperation 

使用方法:

n定义操作并加入到队列
self.myQueue = [[NSOperationQueue alloc] init];
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{ [self operationAction:@"BlockOperation"];}];n将操作加入到队列[self.myQueue addOperation:op];

这种
NSBlockOperation是默认的异步的并行队列

设定dependency能够改成串行并列
 // 设定运行顺序, 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];



这两种方式的差别是:前一种一调用就会马上创建一个线程来做事情。而后一种尽管你 alloc 了也 init了,可是要直到我们手动调用 start 启动线程时才会真正去创建线程。这样的延迟实现思想在非常多跟资源相关的地方都实用到。后一种方式我们还能够在启动线程之前。对线程进行配置,比方设置 stack 大小,线程优先级。



另一种间接的方式。更加方便,我们甚至不须要显式编写 NSThread 相关代码。那就是利用 NSObject 的类方法 performSelectorInBackground:withObject: 来创建一个线程:
[myObj performSelectorInBackground:@selector(myThreadMainMethod) withObject:nil];
其效果与 NSThread 的 detachNewThreadSelector:toTarget:withObject: 是一样的。


相关文章