美文网首页ios开发iOS记录iOS学习笔记2017-3-29
ios初级 (线程与队列的关系,傻瓜学线程)

ios初级 (线程与队列的关系,傻瓜学线程)

作者: 傻瓜芃 | 来源:发表于2016-03-07 20:33 被阅读3907次

    简介

    对于许多面试题 会经常问一些比较简单问题 问线程 进程区别 或者线程与队列的到底有什么关系. 线程 和进程关系这里就不讲了比较简单

    线程与队列的关系和区分

    屏幕快照 2016-03-07 下午7.42.31.png

    如图 一个程序只有一个主队列, 并且主队列是一个特殊的串行队列
    所以说主队列是一个串行队列
    绿图(饭堂模型) 并行队列 就是多条线程一起 执行任务没有顺序
    如果把这个图看成一个进程的话 那么这个进程里一共开了四条线程.(一个主线程 三个子线程).

    如何开线程

    在ios里面一共有三种方式 开辟线程 1.NSThread 2.GCD 3.NSOPeration
    第一种很少人会用 他是oc开线程的方法 因为有许多缺点 所以很少人会用(缺点:手动管理线程, 无法利用多核技术)
    第二种 第三种 需要掌握 这里我们主要说说GCD 是如何开线程的
    第三种NSOPeration 是对苹果公司 对GCD 的一个封装(掌握)

    GCD 应用广泛

    自动开线程 ,延迟操作,运用于单例的创建等.

    GCD开线程

    大家都听过异步 和同步吧 其实异步和同步 就是用GCD 来写的
    大家记住一件事
    dispatch_async(dispatch_get_main_queue(), ^{ });异步里参数除非是dispatch_get_main_queue() 这个主队列 其余的包括 全局队列(并行队列) 和串行队列放入这个异步 作为参数时 他们都会自动创建线程

    那么在异步添加到 并行队列(全局队列)与串行队列 都会自动开线程那么他们有什么区别吗?

    全局队列是什么 他是一个系统自带的并行队列 所以大家以后不用创建并行队列 直接用.
    串行队列 需要手动创建 程序里 已经有了一个特殊的串行队列dispatch_get_main_queue()(主队列)主队列比较特殊 异步加入主线程 这个异步不会开启线程 . 会在主线程执行
    但是自定义创建的串行队列 就不一样了

    /**
    *  async -- 并发队列(最常用)
    *  会不会创建线程:会,一般同时开多条
    *  任务的执行方式:并发执行
    */
    - (void)asyncGlobalQueue
    {
      // 获得全局的并发队列
      dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
      
      // 将 任务 添加 全局队列 中去 异步 执行
      dispatch_async(queue, ^{
          NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
      });
      dispatch_async(queue, ^{
          NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
      });
      dispatch_async(queue, ^{
          NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
      });
      dispatch_async(queue, ^{
          NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
      });
      dispatch_async(queue, ^{
          NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
      });
    }
    
    /**
    *  async -- 串行队列(有时候用)
    *  会不会创建线程:会,一般只开1条线程
    *  任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务)
    */
    - (void)asyncSerialQueue
    {
      // 1.创建一个串行队列
      dispatch_queue_t queue = dispatch_queue_create("cn.heima.queue", NULL);
      
      // 2.将任务添加到串行队列中 异步 执行
      dispatch_async(queue, ^{
          NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
      });
      dispatch_async(queue, ^{
          NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
      });
      dispatch_async(queue, ^{
          NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
      });
      dispatch_async(queue, ^{
          NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
      });
      dispatch_async(queue, ^{
          NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
      });
    
    

    把这几行代码粘到你工程中 你就明白了(打印当前线程) 如代码注释所示 异步加入串行队列 无论你写多少异步 加入者个串行队列 他只会开一条线程.
    而异步加入全局队列 你有几个异步那么他开几个线程(最好不要超过5个).

    线程的锁死

    简单的锁死 有些人 会在主线程中 执行dispatch_sync(dispatch_get_main_queue(), ^{ });
    这一行的代码 这样会造成锁死

    原因

    写了这句话他会加入主线程队列里 等待主线程完成 才回返回block里面的内容.但是当程序运行到这行代码 由于主线程没有完成 block 不会有返回.并且也不会跳过这行代码 所以就造成了死锁现象.

    主队列和主线程的区别

    代码描述[NSOperationQueue mainQueue]主队列 [NSThread mainThread]主线程

    二者关系 主队列里 必须有一个主线程 主队列里可以在加线程

    同步加入全局队列要注意的是

    dispatch_sync 在全局队列是可以写的 等主队列执行完了 它再执行就是了 没什么大不了

    加在主队列 含义是就是 加在主队列执行完后 了你才能执行.(例如更新ui)

    相关文章

      网友评论

      • 郑明明:问你个问题,串行队列一定是只有一条线程吗
        傻瓜芃:@郑明明 应用较少。举例比如某些情况下 必须a完成才能执行b这种情况下可以
        郑明明:@傻瓜芃 什么情况下呢
        傻瓜芃:@郑明明 可以有多条
      • 4622736b50c4:错别字好多
      • 116911e074e1:为什么男人特别讨厌女人的猜忌? 专家回复: 因为猜的太准了!科学证明:女人找茬的时候智商仅次于爱因斯坦,女人发火的时候战斗力仅次于奥特曼,女人发疯的时候危险性仅次于藏獒!先生们,放弃抵抗吧,女人是地球上唯一可以每月流血一周而不死的生物。你惹不起的!宠她,才是唯一的出路!女人讲理吗?男士的回答是“不讲理!”请问,你明明知道她不讲理,你还和她讲理!你脑残啊。预祝三月八号美女节日愉快!

      本文标题:ios初级 (线程与队列的关系,傻瓜学线程)

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