iOS开发的多线程复习

第一次学习

核心知识点

1、主队列,专门用来在主线程上调度任务的队列,不会开启线程,以先进先出的方式,在主线程空闲时才会调用队列中的任务在主线程执行,如果当前主线程正在有任务执行, \color{red}{那么无论主队列中当前被添加了什么任务,都不会被调度}
2、 线 \color{red}{主队列必须等主线程空闲的时候,才会去执行。}
3、 d i s p a t c h m a i n ( 线 \color{red}{dispatchmain()就是这货让主队列的任务在非主线程运行}
意思是这个方法会阻塞主线程,然后在其它线程中执行主队列中的任务。
4、runloop和queue各自维护着自己的一个任务队列,在runloop的每个周期里面,会检测自身的任务队列里面是否存在待执行的task并且执行。但主线程的情况比较特殊,在main runloop的每个周期,会去检测main queue是否存在待执行任务,如果存在,那么copy到自身的任务队列中执行
(摘自(https://www.jianshu.com/p/210d2e867782))

代码

1、代码1

dispatch_queue_t queue = dispatch_queue_create("队列1", DISPATCH_QUEUE_SERIAL);
    NSLog(@"A+++我是任务2");
    //开启新线程
    dispatch_async(queue, ^{
        NSLog(@"B++++我是任务1");
    });
    NSLog(@"C+++++方法执行结束");

问题:b和c任务谁先执行。答案,b和c会交替运行。因为async会开辟新的线程,与主线程并行。
线 线 \color{red}{但异步并一定创建新的线程,当异步的数量多时,线程会复用}

2、代码2

dispatch_queue_t  mainQueue =    dispatch_get_main_queue();
        NSLog(@"A++++我是任务2");
        ///开启新线程
        dispatch_async(mainQueue, ^{
                NSLog(@"B++++我是任务1");
        });

      [self method1];
      
- (void)method {
      NSLog(@"C++++我是任务1");
}

执行顺序acb 队列先进先出,这跟上面的区别在于mainQueue是主队列,主队列是同步队列,实行FIFO原则。
3、代码3

 dispatch_queue_t  aSerialQueue = dispatch_queue_create("xxx_name", DISPATCH_QUEUE_SERIAL);
    dispatch_async(aSerialQueue, ^{
        [self method];
    });
    NSLog(@"test: hello");
    dispatch_sync(aSerialQueue, ^{
       [self method];
    });
    NSLog(@"nihao");
    [self method];

问题:加入method执行完要花5分钟,这些所有执行完,要花多少时间。
答案:15分钟
aSerialQueue 是串行队列,串行队列采用FIFO(先进先出)原则,所以不管外面asyn还是sync,一共实现时间10分钟,dispatch_sync堵塞了后面的[self method],一共花了15分钟。
4、代码4

 dispatch_queue_t queue = dispatch_queue_create("dddd", DISPATCH_QUEUE_CONCURRENT);
   __block NSInteger i = 10;
    dispatch_async(queue, ^{
        NSLog(@"print yang i %d",i);
        NSLog(@"print yang %@",[NSThread currentThread]);
    });
    [self dosome];//耗时操作
     i = 20;

打印结果:10,20随机;如果queue换成普通同步队列,这里也是交互出现结果,使用这种方式会创建新的线程(可能会复用之前在这个block里面创建的线程),所以用同步队列还是异步,队列都一样,随机。但如果queue主队列,那就是20(必须等主线程上其他执行完才行)。

问题

1、dispatch_async会开启线程吗?不一定,如果参数选择是主队列,就不会开启新线程,非主队列会开启线程。
2、死锁的原因

 dispatch_sync(dispatch_get_main_queue(), ^{
        ////1
    });
   ///2

原因跟2类似,1和2相互等待

第二次学习

1、

 NSOperationQueue *queue=[[NSOperationQueue alloc] init];
    //创建操作
    NSBlockOperation *operation1=[NSBlockOperation blockOperationWithBlock:^(){
        NSLog(@"执行第1次操作,线程:%@",[NSThread currentThread]);
    }];
    NSBlockOperation *operation2=[NSBlockOperation blockOperationWithBlock:^(){
        NSLog(@"执行第2次操作,线程:%@",[NSThread currentThread]);
    }];
    NSBlockOperation *operation3=[NSBlockOperation blockOperationWithBlock:^(){
        NSLog(@"执行第3次操作,线程:%@",[NSThread currentThread]);
    }];
    //添加依赖
    [operation1 addDependency:operation2];
    [operation2 addDependency:operation3];
    //将操作添加到队列中去
    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];

2、纠正了我一个错误,观点,以前以为kd(our app simple name)我写的那个下载框架是顺序下载,是不对的
3、NSURLSession只能是不一样的id,这个很奇怪啊,二期那个配置host max数量的没什么用

猜你喜欢

转载自blog.csdn.net/u014544346/article/details/95616150