IOS多线程

什么是多线程:

什么是进程 ?

想说清什么是多线程,我们还需要了解一些其他的东西,什么是进程,网上大多数资料解释是一个运行中的应用程序,举个例子,比如电脑上运行的QQ,微信。。。是不是感觉有点抽象,这样去想,不管是QQ还是微信他们只是一个应用程序,应用程序运行需要内存存储一些东西,比如变量常量方法函数。。。这些东西运行需要执行顺序和计算,然后根据我们编程逻辑在屏幕上显示出我们所想要的东西,计算机上有若干个应用程序,我们不能任由他们在内存或CPU上乱搞吧,这样不就混乱了,因此程序在运行时会创建一个属于自己的空间,在这个空间里做自己想要做的事情,那么这个空间就是我们要说的进程。

__ 什么是线程 ?__

说了这么多,可能有人会问这和多线程有毛关系,再说这个毛关系之前我们先理清什么是线程,网上大多数资料的解释是把一堆要执行的指令串联起来称为线程,这又是什么鬼东西,好了这确实不是什么鬼东西,说清楚就好了,举个QQ登录的例子,我们一般打开QQ登录进入之后才能看到我们的好友,这句话我们分析下是怎么回事,我们要看到我们的QQ好友,那么我们必须输入账号密码,再去点击登录按钮,然后我们就看到我们的QQ好友了,是不是这些操作就像一条线一样贯穿我们最终看到QQ好友,明白线程了吧。

什么是多线程 ?

我们再来看看多线程,网上解释是同一时刻有多条线程执行我们称为多线程,说到这里有人又开始糊涂了,CPU不是一个核心吗,一次只能执行一条线程,怎么突然又跑出多个线程来,不符合科学呀,不要激动,我解释下,首先我肯定一点你所说的是正确的,看来你对CPU的执行还算了解,其实说到底CPU同时还是在执行一个线程,那又是怎么同时执行多条线程了,他会把多个线程切分成小块,因为运行速度特别快,他每秒可能从多个线程中个取出一块来执行,造成我们视觉的效果就是同一时刻就好像有多条线程在执行。

IOS中的多线程#####

IOS中常用到的多线程处理有三个:

  1. NSThread
  2. GCD
  3. NSOperation/NSOperationQueue

NSThread:

GCD:
GCD是苹果多核编程处理的解决方案,底层通过纯C语言实现。在开始学习GCD时首先必须了解几个概念:
1.任务:做什么操作,实现什么功能。
1.1 同步操作:多个任务执行中,会阻碍下一个任务执行,直到第一个任务执行完成,才会执行下一个任务。
1.2 异步操作:多个任务执行中,相互不受影响,各执行个的任务。
2.队列:将定义的任务存放起来。
2.1 串行队列:队列中的任务执行通道只有一条,同一时刻只会执行一个任务。
2.2 并行队列:队列中的任物执行通道有多条,同一时刻会执行多个任务。

Paste_Image.png

GCD中基本对象的创建

   // 创建串行队列
    dispatch_queue_t queue1 = dispatch_queue_create("tk.bournetestQueue", NULL);
    dispatch_queue_t queue2 = dispatch_queue_create("tk.bournetestQueue", DISPATCH_QUEUE_SERIAL);
    
    // 创建并行队列
    dispatch_queue_t queue3 = dispatch_queue_create("tk.bournetestQueue", DISPATCH_QUEUE_CONCURRENT);

    // DISPATCH_QUEUE_PRIORITY_HIGH         //高
    // DISPATCH_QUEUE_PRIORITY_DEFAULT      //默认(中)
    // DISPATCH_QUEUE_PRIORITY_LOW          // 底
    // DISPATCH_QUEUE_PRIORITY_BACKGROUND   // 后台
    // 创建全局并行队列
    dispatch_queue_t queue4 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

    // 创建主线程
    dispatch_queue_t queue5 = dispatch_get_main_queue();

    // 创建同步任务
    dispatch_sync(queue1, ^{
       //do some thing ...
    });
    
    // 创建异步任务
    dispatch_async(queue2, ^{
       // do some thing  ...
    });

测试

 // 事例1(串行队列 异步执行)
    NSLog(@"current thread%@",[NSThread currentThread]);
    
    dispatch_queue_t queue = dispatch_queue_create("22", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(queue, ^{
        NSLog(@"download image1 %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"download image2 %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"download image3 %@",[NSThread currentThread]);
    });
    // 总结:创建新的线程
//    2016-07-04 14:47:29.348 多线程Demo[1914:96867] current thread<NSThread: 0x100306210>{number = 1, name = main}
//    2016-07-04 14:47:29.350 多线程Demo[1914:96891] download image1 <NSThread: 0x100308580>{number = 2, name = (null)}
//    2016-07-04 14:47:29.351 多线程Demo[1914:96891] download image2 <NSThread: 0x100308580>{number = 2, name = (null)}
//    2016-07-04 14:47:29.351 多线程Demo[1914:96891] download image3 <NSThread: 0x100308580>{number = 2, name = (null)}
    
    // 事例2(并行队列 异步执行)
    NSLog(@"current thread%@",[NSThread currentThread]);
    
    dispatch_queue_t queue = dispatch_queue_create("22", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        NSLog(@"download image1 %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"download image2 %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"download image3 %@",[NSThread currentThread]);
    });
    // 总结:创建新的线程
//    2016-07-04 14:49:56.728 多线程Demo[1940:98159] current thread<NSThread: 0x100502b50>{number = 1, name = main}
//    2016-07-04 14:49:56.731 多线程Demo[1940:98189] download image1 <NSThread: 0x100108560>{number = 2, name = (null)}
//    2016-07-04 14:49:56.731 多线程Demo[1940:98189] download image2 <NSThread: 0x100108560>{number = 2, name = (null)}
//    2016-07-04 14:49:56.731 多线程Demo[1940:98189] download image3 <NSThread: 0x100108560>{number = 2, name = (null)}
    
    // 事例3(串行队列 同步执行)
    NSLog(@"current thread%@",[NSThread currentThread]);
    
    dispatch_queue_t queue = dispatch_queue_create("22", DISPATCH_QUEUE_SERIAL);
    
    dispatch_sync(queue, ^{
        NSLog(@"download image1 %@",[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"download image2 %@",[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"download image3 %@",[NSThread currentThread]);
    });
    // 总结:不会创建新的线程
//    2016-07-04 14:52:42.806 多线程Demo[1965:99334] current thread<NSThread: 0x1002063b0>{number = 1, name = main}
//    2016-07-04 14:52:42.807 多线程Demo[1965:99334] download image1 <NSThread: 0x1002063b0>{number = 1, name = main}
//    2016-07-04 14:52:42.807 多线程Demo[1965:99334] download image2 <NSThread: 0x1002063b0>{number = 1, name = main}
//    2016-07-04 14:52:42.807 多线程Demo[1965:99334] download image3 <NSThread: 0x1002063b0>{number = 1, name = main}
    
    // 事例4(并行队列 同步执行)
        NSLog(@"current thread%@",[NSThread currentThread]);
    
        dispatch_queue_t queue = dispatch_queue_create("22", DISPATCH_QUEUE_CONCURRENT);
    
        dispatch_sync(queue, ^{
            NSLog(@"download image1 %@",[NSThread currentThread]);
        });
    
        dispatch_sync(queue, ^{
            NSLog(@"download image2 %@",[NSThread currentThread]);
        });
    
        dispatch_sync(queue, ^{
            NSLog(@"download image3 %@",[NSThread currentThread]);
        });
     // 总结:不会创建新的线程
//    2016-07-04 14:53:49.116 多线程Demo[1982:99780] current thread<NSThread: 0x100105010>{number = 1, name = main}
//    2016-07-04 14:53:49.117 多线程Demo[1982:99780] download image1 <NSThread: 0x100105010>{number = 1, name = main}
//    2016-07-04 14:53:49.117 多线程Demo[1982:99780] download image2 <NSThread: 0x100105010>{number = 1, name = main}
//    2016-07-04 14:53:49.117 多线程Demo[1982:99780] download image3 <NSThread: 0x100105010>{number = 1, name = main}
    
    // 事例5(主线程,异步执行)
    dispatch_queue_t queue = dispatch_get_main_queue();
    NSLog(@"current thread%@",[NSThread currentThread]);
    
    dispatch_async(queue, ^{
        NSLog(@"download image1 %@",[NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"download image2 %@",[NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"download image3 %@",[NSThread currentThread]);
    });
    
    // 总结:不会创建新的线程
//    2016-07-04 14:58:01.040 多线程Demo[2023:101512] current thread<NSThread: 0x100602b50>{number = 1, name = main}
//    2016-07-04 14:58:01.042 多线程Demo[2023:101512] download image1 <NSThread: 0x100602b50>{number = 1, name = main}
//    2016-07-04 14:58:01.042 多线程Demo[2023:101512] download image2 <NSThread: 0x100602b50>{number = 1, name = main}
//    2016-07-04 14:58:01.042 多线程Demo[2023:101512] download image3 <NSThread: 0x100602b50>{number = 1, name = main}
    
    // 事例6(主线程,同步操作)
    dispatch_queue_t queue = dispatch_get_main_queue();
    NSLog(@"current thread%@",[NSThread currentThread]);
    dispatch_sync(queue, ^{
        NSLog(@"download image1 %@",[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"download image2 %@",[NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"download image3 %@",[NSThread currentThread]);
    });
    // 结论:主线程的同步操作,
//    2016-07-04 14:58:55.638 多线程Demo[2041:101984] current thread<NSThread: 0x100202cc0>{number = 1, name = main}
    
    // 事例7(全局,同步操作)
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    NSLog(@"current thread%@",[NSThread currentThread]);
    dispatch_sync(queue, ^{
        NSLog(@"download image1 %@",[NSThread currentThread]);
    });

    dispatch_sync(queue, ^{
        NSLog(@"download image2 %@",[NSThread currentThread]);
    });

    dispatch_sync(queue, ^{
        NSLog(@"download image3 %@",[NSThread currentThread]);
    });
    // 结论:不会创建新线程
//    2016-07-04 15:03:41.035 多线程Demo[2078:103856] current thread<NSThread: 0x1002050b0>{number = 1, name = main}
//    2016-07-04 15:03:41.036 多线程Demo[2078:103856] download image1 <NSThread: 0x1002050b0>{number = 1, name = main}
//    2016-07-04 15:03:41.036 多线程Demo[2078:103856] download image2 <NSThread: 0x1002050b0>{number = 1, name = main}
//    2016-07-04 15:03:41.036 多线程Demo[2078:103856] download image3 <NSThread: 0x1002050b0>{number = 1, name = main}
    
    // 事例8(全局,异步操作)
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    NSLog(@"current thread%@",[NSThread currentThread]);
    dispatch_async(queue, ^{
        NSLog(@"download image1 %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"download image2 %@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"download image3 %@",[NSThread currentThread]);
    });
    // 结论:会创建新线程,每个任务都会创建一个线程
//    2016-07-04 15:05:02.274 多线程Demo[2108:104753] current thread<NSThread: 0x1001052f0>{number = 1, name = main}
//    2016-07-04 15:05:02.276 多线程Demo[2108:104785] download image2 <NSThread: 0x1005004d0>{number = 2, name = (null)}
//    2016-07-04 15:05:02.276 多线程Demo[2108:104788] download image3 <NSThread: 0x100500e70>{number = 3, name = (null)}
//    2016-07-04 15:05:02.276 多线程Demo[2108:104787] download image1 <NSThread: 0x100701a20>{number = 4, name = (null)}
 总结:只有异步操作才能够创建新的线程,同步操作不会创建新的线程(主线程这里除外)

NSOperation/NSOperationQueue
NSOperation/NSOperationQueue是苹果公司对GCD的封装,完全的面向对象,让开发者使用起来更加方便,对于他的理解NSOperation类似GCD中的任务,NSOperationQueue类似GCD中的队列,好了具体操作看一下代码实现。

最后:文章可能存在错别字或者理解不到位的地方,欢迎挑刺,如果你也是一枚IOS爱好者,请加入我们的QQ群:126440594

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 多线程 在iOS开发中为提高程序的运行效率会将比较耗时的操作放在子线程中执行,iOS系统进程默认启动一个主线程,用...
    郭豪豪阅读 2,586评论 0 4
  • 一、基本概念 线程是用来执行任务的,线程彻底执行完任务A才能执行任务B,为了同时执行两个任务,产生了多线程 1、进...
    空白Null阅读 658评论 0 3
  • 欢迎大家指出文章中需要改正或者需要补充的地方,我会及时更新,非常感谢。 一. 多线程基础 1. 进程 进程是指在系...
    xx_cc阅读 7,169评论 11 70
  • 前言 我对于http缓存的认知总是停留在略知一二的状态,毕竟实际工作中用的比较少-_-||但作为一个严谨的程序员,...
    ITgecko阅读 696评论 0 2
  • 放下,也许真的没有那么难。 如果你愿意, 你可以为了某样东西, 放下你所挚爱的,沉迷的 亦或是, 在现实的压力下,...
    AOX傲雪桑阅读 228评论 0 0