iOS开发多线程

2017-01-12  本文已影响15人  忘川_之上

这段时间一直在自学html,js,css。今天闲来无事,还是决定好好复习复习iOS的代码,前天swift之父Chris Lattner离开了苹果,群里热闹:“swift bug谁来修改?swift何去何从?”  好了扯远了,还是整理下多线程吧。

NSThread在实际开发中用到的很少了,(直说了除了[NSThread currentThread],我都不用),代码量以及需要手动去管理,并且线程管理相对不方便,所以对于NSThread不做介绍了,记住[NSThread currentThread]可以用来调试即可。

一、GCD需要掌握的

1、串行队列的创建

dispatch_queue_t q = dispatch_queue_create("com.example.gcd.mySerialDispatchQueue", NULL);

a、串行队列开启同步任务,在主线程顺序执行

dispatch_queue_t q = dispatch_queue_create("com.example.gcd.mySerialDispatchQueue", NULL);

for (int i = 0; i < 10; i ++) {

dispatch_sync(q, ^{

NSLog(@"___%@__%d",[NSThread currentThread],i);

});}

b、串行队列开启异步任务 开启2号(开启一个)线程 ,顺序执行

for (int i = 0; i < 10; i ++) {

dispatch_async(q, ^{

//串行队列 异步任务 开启2号(开启一个)线程  顺序执行

NSLog(@"%@__%d",[NSThread currentThread],i);

});}

c、串行队列中无论是同步任务还是异步任务,只要在这些任务中又开启了同步任务线程就会被锁死。

2、并行队列的创建

dispatch_queue_t q = dispatch_queue_create("com.tysx.189", DISPATCH_QUEUE_CONCURRENT); 

与串行的区别DISPATCH_QUEUE_CONCURRENT与NULL的区别。

a、并行队列开启同步任务在主线程 顺序执行

dispatch_queue_t q = dispatch_queue_create("com.tysx.189", DISPATCH_QUEUE_CONCURRENT);

for (int i = 0; i < 10; i ++) {

dispatch_sync(q, ^{

NSLog(@"1%@___%d",[NSThread currentThread],i);

});}

b、并行队列开启异步任务会开多个线程 无序执行

for (int i = 0; i < 10; i ++) {

dispatch_async(q, ^{

NSLog(@"2%@___%d",[NSThread currentThread],i);

});}

c、并行队列的好处是可以随意嵌套而不会出现线程死锁情况,什么是线程死锁,我的理解是这样的,在主线程中,又开启了一个主线程的任务,那么由于该主线程永远都不会结束,所以开启的任务将永远都不会被执行到。

3、全局主队列只能开异步任务,同步任务会死锁,并且异步任务在主线程 顺序执行

for (int i = 0; i < 10; i ++) {

dispatch_async(dispatch_get_main_queue(), ^{

// 只能在主线程中执行的处理

NSLog(@"%@__%d",[NSThread currentThread],i);

});}

4、全局组队列的创建,类似于并行队列,同步任务主线程顺序执行,异步任务开多个线程无序执行。

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

5、这边只有十次循环都结束的时候 才会调用下面的nslog(done)

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_group_t group = dispatch_group_create();

for (int i = 0; i < 10; i ++) {

dispatch_group_async(group, queue, ^{

NSLog(@"%d",i);

});}

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

NSLog(@"done");});

6、相当于线程依赖吧,前面2个执行完然后 执行barrier 然后再执行下面的内容

dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(concurrentQueue, ^(){

NSLog(@"dispatch-1");

});

dispatch_async(concurrentQueue, ^(){

NSLog(@"dispatch-2");

});

7、相当于线程依赖吧,前面2个执行完然后 执行barrier 然后再执行下面的内容

dispatch_barrier_async(concurrentQueue, ^(){

NSLog(@"dispatch-barrier");

});

dispatch_async(concurrentQueue, ^(){

NSLog(@"dispatch-3");

});

dispatch_async(concurrentQueue, ^(){

NSLog(@"dispatch-4");

});

/**

*  下面方法 相当于一个for循环 只是在全部循环完成后才会执行done

*/

dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_apply(10, queue, ^(size_t index){

NSLog(@"%zu",index);

});

NSLog(@"done");

二、NSOperationQueue

1、将nstimer 加入到runloop

+ (void)ADDTimer:(NSTimer *)timer{

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

}

2、常用会到主线程方法

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

//这个可以成为回到主线程的方法。

//        [self Printf];

}];

3、 开启子线程

[[[NSOperationQueue alloc]init] addOperationWithBlock:^{

//无序的开线程完成任务。

//        [self Printf];

}];

4、这边如果设置 queue.maxConcurrentOperationCount = 1; 则相当于串行队列,如果不设置则相当于并行队列

NSOperationQueue * queue1 = [[NSOperationQueue alloc]init];

//    queue.maxConcurrentOperationCount = 1;

for (int i  = 0; i < 10; i ++) {

[queue1 addOperationWithBlock:^{

NSLog(@"%d",i);

//            [self Printf];

}];

5、线程依赖的执行

NSOperationQueue * queue = [[NSOperationQueue alloc]init];

NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{

NSLog(@"1");

}];

NSBlockOperation * op2 = [NSBlockOperation blockOperationWithBlock:^{

NSLog(@"2");

}];

NSBlockOperation * op3 = [NSBlockOperation blockOperationWithBlock:^{

NSLog(@"3");

}];

//adddependency 这里是建立依赖关系,就是说只有3执行完了 才执行2  然后执行1

[op1 addDependency:op2];

[op2 addDependency:op3];

[queue addOperation:op3];

//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

//        [queue addOperation:op3];

//    });

// 会阻塞当前线程,等到某个operation执行完毕

//    [op2 waitUntilFinished];

[queue addOperation:op2];

[queue addOperation:op1];

三、关于对同一个对象访问的处理

进入Xcode 8.0 以后 增加了新的调试功能。

进入eidt secheme 勾选thread sanitlzer 和pause on issues

这样在项目运行的时候,如果出现对于同一个对象进行的重复访问,则会提示出来。

这是时候可以考虑进行 加锁和互斥处理。详细信息可以去百度进行搜索,这边不做罗列。

上一篇下一篇

猜你喜欢

热点阅读