美文网首页
iOS开发多线程

iOS开发多线程

作者: 忘川_之上 | 来源:发表于2017-01-12 17:48 被阅读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

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

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

    相关文章

      网友评论

          本文标题:iOS开发多线程

          本文链接:https://www.haomeiwen.com/subject/rkadbttx.html