iOS多線(xiàn)程之GCD

多線(xiàn)程相關(guān)概念

進(jìn)程與線(xiàn)程

進(jìn)程概念: 進(jìn)程是程序在計(jì)算機(jī)上的一次執(zhí)行活動(dòng)脊阴,打開(kāi)一個(gè)app披摄,就開(kāi)啟了一個(gè)進(jìn)程帅韧,可包含多個(gè)線(xiàn)程榨为。
線(xiàn)程概念: 獨(dú)立執(zhí)行的代碼段惨好,一個(gè)線(xiàn)程同時(shí)間只能執(zhí)行一個(gè)任務(wù),反之多線(xiàn)程并發(fā)就可以在同一時(shí)間執(zhí)行多個(gè)任務(wù)随闺。
iOS程序中日川,主線(xiàn)程(又叫作UI線(xiàn)程)主要任務(wù)是處理UI事件,顯示和刷新UI矩乐,(只有主線(xiàn)程有直接修改UI的能力)耗時(shí)的操作放在子線(xiàn)程(又叫作后臺(tái)線(xiàn)程龄句、異步線(xiàn)程)回论。在iOS中開(kāi)子線(xiàn)程去處理耗時(shí)的操作,可以有效提高程序的執(zhí)行效率分歇,提高資源利用率傀蓉。但是開(kāi)啟線(xiàn)程會(huì)占用一定的內(nèi)存,(主線(xiàn)程的堆棧大小是1M职抡,第二個(gè)線(xiàn)程開(kāi)始都是512KB葬燎,并且該值不能通過(guò)編譯器開(kāi)關(guān)或線(xiàn)程API函數(shù)來(lái)更改)降低程序的性能。所以一般不要同時(shí)開(kāi)很多線(xiàn)程缚甩。

線(xiàn)程相關(guān)

同步線(xiàn)程:同步線(xiàn)程會(huì)阻塞當(dāng)前線(xiàn)程去執(zhí)行線(xiàn)程內(nèi)的任務(wù)谱净,執(zhí)行完之后才會(huì)反回當(dāng)前線(xiàn)程。
異步線(xiàn)程:異步線(xiàn)程不會(huì)阻塞當(dāng)前線(xiàn)程擅威,會(huì)開(kāi)啟其他線(xiàn)程去執(zhí)行線(xiàn)程內(nèi)的任務(wù)壕探。
串行隊(duì)列:線(xiàn)程任務(wù)按先后順序逐個(gè)執(zhí)行(需要等待隊(duì)列里面前面的任務(wù)執(zhí)行完之后再執(zhí)行新的任務(wù))。
并發(fā)隊(duì)列:多個(gè)任務(wù)按添加順序一起開(kāi)始執(zhí)行(不用等待前面的任務(wù)執(zhí)行完再執(zhí)行新的任務(wù))郊丛,但是添加間隔往往忽略不計(jì)李请,所以看著像是一起執(zhí)行的。
并發(fā)VS并行:并行是基于多核設(shè)備的厉熟,并行一定是并發(fā)捻艳,并發(fā)不一定是并行。

多線(xiàn)程中會(huì)出現(xiàn)的問(wèn)題

Critical Section(臨界代碼段)
指的是不能同時(shí)被兩個(gè)線(xiàn)程訪(fǎng)問(wèn)的代碼段庆猫,比如一個(gè)變量认轨,被并發(fā)進(jìn)程訪(fǎng)問(wèn)后可能會(huì)改變變量值,造成數(shù)據(jù)污染(數(shù)據(jù)共享問(wèn)題)月培。
Race Condition (競(jìng)態(tài)條件)
當(dāng)多個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn)共享的數(shù)據(jù)時(shí)嘁字,會(huì)發(fā)生爭(zhēng)用情形,第一個(gè)線(xiàn)程讀取改變了一個(gè)變量的值杉畜,第二個(gè)線(xiàn)程也讀取改變了這個(gè)變量的值纪蜒,兩個(gè)線(xiàn)程同時(shí)操作了該變量,此時(shí)他們會(huì)發(fā)生競(jìng)爭(zhēng)來(lái)看哪個(gè)線(xiàn)程會(huì)最后寫(xiě)入這個(gè)變量此叠,最后被寫(xiě)入的值將會(huì)被保留下來(lái)纯续。
Deadlock (死鎖)
兩個(gè)(多個(gè))線(xiàn)程都要等待對(duì)方完成某個(gè)操作才能進(jìn)行下一步,這時(shí)就會(huì)發(fā)生死鎖灭袁。
Thread Safe(線(xiàn)程安全)
一段線(xiàn)程安全的代碼(對(duì)象)猬错,可以同時(shí)被多個(gè)線(xiàn)程或并發(fā)的任務(wù)調(diào)度,不會(huì)產(chǎn)生問(wèn)題茸歧,非線(xiàn)程安全的只能按次序被訪(fǎng)問(wèn)倦炒。
所有Mutable對(duì)象都是非線(xiàn)程安全的,所有Immutable對(duì)象都是線(xiàn)程安全的软瞎,使用Mutable對(duì)象逢唤,一定要用同步鎖來(lái)同步訪(fǎng)問(wèn)(@synchronized)拉讯。
互斥鎖:能夠防止多線(xiàn)程搶奪造成的數(shù)據(jù)安全問(wèn)題,但是需要消耗大量的資源
原子屬性(atomic)加鎖
atomic: 原子屬性鳖藕,為setter方法加鎖魔慷,將屬性以atomic的形式來(lái)聲明,該屬性變量就能支持互斥鎖了著恩。
nonatomic: 非原子屬性盖彭,不會(huì)為setter方法加鎖,聲明為該屬性的變量页滚,客戶(hù)端應(yīng)盡量避免多線(xiàn)程爭(zhēng)奪同一資源。
Context Switch (上下文切換)
當(dāng)一個(gè)進(jìn)程中有多個(gè)線(xiàn)程來(lái)回切換時(shí)铺呵,context switch用來(lái)記錄執(zhí)行狀態(tài)裹驰,這樣的進(jìn)程和一般的多線(xiàn)程進(jìn)程沒(méi)有太大差別,但會(huì)產(chǎn)生一些額外的開(kāi)銷(xiāo)片挂。

多線(xiàn)程編程技術(shù)的優(yōu)缺點(diǎn)比較

NSThread (抽象層次:低)
優(yōu)點(diǎn):輕量級(jí)幻林,簡(jiǎn)單易用,可以直接操作線(xiàn)程對(duì)象
缺點(diǎn): 需要自己管理線(xiàn)程的生命周期音念,線(xiàn)程同步沪饺。線(xiàn)程同步對(duì)數(shù)據(jù)的加鎖會(huì)有一定的系統(tǒng)開(kāi)銷(xiāo)。
Cocoa NSOperation (抽象層次:中)
優(yōu)點(diǎn):不需要關(guān)心線(xiàn)程管理闷愤,數(shù)據(jù)同步的事情整葡,可以把精力放在學(xué)要執(zhí)行的操作上〖テ辏基于GCD遭居,是對(duì)GCD 的封裝,比GCD更加面向?qū)ο?br> 缺點(diǎn): NSOperation是個(gè)抽象類(lèi)旬渠,使用它必須使用它的子類(lèi)俱萍,可以實(shí)現(xiàn)它或者使用它定義好的兩個(gè)子類(lèi)NSInvocationOperation、NSBlockOperation.
GCD 全稱(chēng)Grand Center Dispatch (抽象層次:高)

優(yōu)點(diǎn):是 Apple 開(kāi)發(fā)的一個(gè)多核編程的解決方法告丢,簡(jiǎn)單易用枪蘑,效率高,速度快岖免,基于C語(yǔ)言岳颇,更底層更高效,并且不是Cocoa框架的一部分颅湘,自動(dòng)管理線(xiàn)程生命周期(創(chuàng)建線(xiàn)程赦役、調(diào)度任務(wù)、銷(xiāo)毀線(xiàn)程)栅炒。
缺點(diǎn): 使用GCD的場(chǎng)景如果很復(fù)雜掂摔,就有非常大的可能遇到死鎖問(wèn)題术羔。

GCD抽象層次最高,使用也簡(jiǎn)單乙漓,因此级历,蘋(píng)果也推薦使用GCD

GCD中的隊(duì)列類(lèi)型

GCD編程的核心就是dispatch隊(duì)列,dispatch block的執(zhí)行最終都會(huì)放進(jìn)某個(gè)隊(duì)列中去進(jìn)行叭披。

The main queue(主線(xiàn)程串行隊(duì)列): 與主線(xiàn)程功能相同寥殖,提交至Main queue的任務(wù)會(huì)在主線(xiàn)程中執(zhí)行,
Main queue 可以通過(guò)dispatch_get_main_queue()來(lái)獲取涩蜘。
Global queue(全局并發(fā)隊(duì)列): 全局并發(fā)隊(duì)列由整個(gè)進(jìn)程共享嚼贡,有高、中(默認(rèn))同诫、低粤策、后臺(tái)四個(gè)優(yōu)先級(jí)別。
Global queue 可以通過(guò)調(diào)用dispatch_get_global_queue函數(shù)來(lái)獲任蠼选(可以設(shè)置優(yōu)先級(jí))
Custom queue (自定義隊(duì)列): 可以為串行叮盘,也可以為并發(fā)。
Custom queue 可以通過(guò)dispatch_queue_create()來(lái)獲扰场柔吼;
Group queue (隊(duì)列組):將多線(xiàn)程進(jìn)行分組,最大的好處是可獲知所有線(xiàn)程的完成情況丙唧。
Group queue 可以通過(guò)調(diào)用dispatch_group_create()來(lái)獲取愈魏,通過(guò)dispatch_group_notify,可以直接監(jiān)聽(tīng)組里所有線(xiàn)程完成情況。

重點(diǎn)來(lái)了哈

GCD在項(xiàng)目中的實(shí)際應(yīng)用

GCD在項(xiàng)目中的實(shí)際應(yīng)用

GCD在項(xiàng)目中的實(shí)際應(yīng)用(一定要說(shuō)夠三遍O爰省r蚪洹!)

以下請(qǐng)求以afn為例

場(chǎng)景一

個(gè)頁(yè)面多個(gè)網(wǎng)絡(luò)請(qǐng)求沼琉,并且多個(gè)請(qǐng)求同時(shí)執(zhí)行北苟,都執(zhí)行完成以后進(jìn)行數(shù)據(jù)操作
實(shí)現(xiàn)方式1:dipatch_group

AFHTTPSessionManager *MANAGER = [AFHTTPSessionManager manager];
    dispatch_group_enter(self.group);
    [MANAGER POST:@"" parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        dispatch_group_leave(self.group);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        dispatch_group_leave(self.group);
    }];

    dispatch_group_enter(self.group);
    [MANAGER POST:@"" parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
        dispatch_group_leave(self.group);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        dispatch_group_leave(self.group);
    }];
    dispatch_group_notify(self.group, self.chquue, ^{
        NSLog(@"11111");
    });

其他類(lèi)似代碼實(shí)現(xiàn)相同效果

dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t conQueue = dispatch_queue_create("fsfsdfsf2", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t seQueue = dispatch_queue_create("asdsadasdasda", NULL);
    dispatch_queue_t seQueue1 = dispatch_queue_create("asdsadasasdadassda", NULL);
//
//
    
    dispatch_group_enter(group);
    dispatch_async(conQueue, ^{
        sleep(6);
        NSLog(@"111111");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(seQueue, ^{
        sleep(2);
        NSLog(@"222222");
        dispatch_group_leave(group);
    });
    dispatch_group_enter(group);
    dispatch_async(seQueue1, ^{
        sleep(4);
        NSLog(@"33333");
        dispatch_group_leave(group);
    });
//
    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"444444");
    });
//
    NSLog(@"hhahahaha");
其中的隊(duì)列可以是不同的隊(duì)列,只要group是同一個(gè)打瘪,都會(huì)得到最后執(zhí)行notify代碼的效果友鼻,如果是同一個(gè)串行隊(duì)列,則會(huì)按照1-2-3-4的順序串行執(zhí)行以上4個(gè)任務(wù)

實(shí)現(xiàn)方式2:dispatch_semaphore

dispatch_async(self.chquue, ^{
        dispatch_semaphore_t SEM = dispatch_semaphore_create(0);
        AFHTTPSessionManager *MANAGER = [AFHTTPSessionManager manager];
        
        [MANAGER POST:@"" parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
            dispatch_semaphore_signal(SEM);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            dispatch_semaphore_signal(SEM);
        }];
        
        dispatch_semaphore_t SEM2 = dispatch_semaphore_create(0);
        [MANAGER POST:@"" parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
            dispatch_semaphore_signal(SEM2);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            dispatch_semaphore_signal(SEM2);
        }];
        dispatch_semaphore_wait(SEM, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(SEM2, DISPATCH_TIME_FOREVER);
        
        NSLog(@"hahaha");
    });
    NSLog(@"hello");
此處為什么要套一個(gè)dispatch_ASYNC呢闺骚?這樣做是為了防止阻塞主線(xiàn)程的任務(wù)執(zhí)行彩扔!
場(chǎng)景二

一個(gè)頁(yè)面多個(gè)網(wǎng)絡(luò)請(qǐng)求,并且多個(gè)請(qǐng)求串執(zhí)行僻爽,下一個(gè)請(qǐng)求需要等待上一個(gè)的請(qǐng)求結(jié)果才能繼續(xù)請(qǐng)求
實(shí)現(xiàn)方式1:dipatch_group虫碉,如何使用group的方式來(lái)實(shí)現(xiàn)這個(gè)需求,歡迎大神提出意見(jiàn)
實(shí)現(xiàn)方式2:dispatch_semaphore

dispatch_async(self.chquue, ^{
        dispatch_semaphore_t SEM = dispatch_semaphore_create(0);
        AFHTTPSessionManager *MANAGER = [AFHTTPSessionManager manager];
        
        [MANAGER POST:@"" parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
            dispatch_semaphore_signal(SEM);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            dispatch_semaphore_signal(SEM);
        }];
        
       dispatch_semaphore_wait(SEM, DISPATCH_TIME_FOREVER);
        [MANAGER POST:@"" parameters:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nonnull responseObject) {
            dispatch_semaphore_signal(SEM);
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            dispatch_semaphore_signal(SEM);
        }];
        dispatch_semaphore_wait(SEM, DISPATCH_TIME_FOREVER);
        
        NSLog(@"hahaha");
    });
    NSLog(@"hello");
這段代碼的關(guān)鍵點(diǎn)是只使用一個(gè)sem來(lái)實(shí)現(xiàn)串行執(zhí)行異步任務(wù)

當(dāng)然如果哪位大神有更好的實(shí)現(xiàn)方式歡迎指點(diǎn)P匕稹敦捧!

場(chǎng)景三

死鎖

dispatch_queue_t serialQueue = dispatch_queue_create("com.dullgrass.serialQueue", DISPATCH_QUEUE_SERIAL);
  dispatch_sync(serialQueue, ^{
      NSLog(@"會(huì)執(zhí)行的代碼");
      //當(dāng)嵌套的這個(gè)任務(wù)是同步且在串行隊(duì)列中執(zhí)行時(shí)须板,就會(huì)造成死鎖
      dispatch_sync(serialQueue, ^{
          NSLog(@"代碼不執(zhí)行");
      });
  });

關(guān)于dispatc_group

dispatch_enter和dispatch_leave要成對(duì)出現(xiàn),否則奔潰兢卵。

補(bǔ)充

關(guān)于dispatch_set_target_queue
場(chǎng)景一

使用dispatch_set_target_queue更改Dispatch Queue的執(zhí)行優(yōu)先級(jí)
dispatch_queue_create函數(shù)生成的DisPatch Queue不管是Serial DisPatch Queue還是Concurrent Dispatch Queue,執(zhí)行的優(yōu)先級(jí)都與默認(rèn)優(yōu)先級(jí)的Global Dispatch queue相同,如果需要變更生成的Dispatch Queue的執(zhí)行優(yōu)先級(jí)則需要使用dispatch_set_target_queue函數(shù)

- (void)testTeagerQueue1 {
2     dispatch_queue_t serialQueue = dispatch_queue_create("com.oukavip.www",NULL);
3     dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0);
4     
5     dispatch_set_target_queue(serialQueue, globalQueue);
6     // 第一個(gè)參數(shù)為要設(shè)置優(yōu)先級(jí)的queue,第二個(gè)參數(shù)是參照物习瑰,既將第一個(gè)queue的優(yōu)先級(jí)和第二個(gè)queue的優(yōu)先級(jí)設(shè)置一樣。
7 }
場(chǎng)景二

使用dispatch_set_target_queue將多個(gè)串行的queue指定到了同一目標(biāo)秽荤,那么著多個(gè)串行queue在目標(biāo)queue上就是同步執(zhí)行的甜奄,不再是并行執(zhí)行。

- (void)testTargetQueue {
  //1.創(chuàng)建目標(biāo)隊(duì)列
  dispatch_queue_t targetQueue = dispatch_queue_create("test.target.queue", DISPATCH_QUEUE_SERIAL);
  
  //2.創(chuàng)建3個(gè)串行隊(duì)列
  dispatch_queue_t queue1 = dispatch_queue_create("test.1", DISPATCH_QUEUE_SERIAL);
  dispatch_queue_t queue2 = dispatch_queue_create("test.2", DISPATCH_QUEUE_SERIAL);
  dispatch_queue_t queue3 = dispatch_queue_create("test.3", DISPATCH_QUEUE_SERIAL);
  
  //3.將3個(gè)串行隊(duì)列分別添加到目標(biāo)隊(duì)列
  dispatch_set_target_queue(queue1, targetQueue);
  dispatch_set_target_queue(queue2, targetQueue);
  dispatch_set_target_queue(queue3, targetQueue);
  
  
  dispatch_async(queue1, ^{
      NSLog(@"1 in");
      [NSThread sleepForTimeInterval:3.f];
      NSLog(@"1 out");
  });
  
  dispatch_async(queue2, ^{
      NSLog(@"2 in");
      [NSThread sleepForTimeInterval:2.f];
      NSLog(@"2 out");
  });
  dispatch_async(queue3, ^{
      NSLog(@"3 in");
      [NSThread sleepForTimeInterval:1.f];
      NSLog(@"3 out");
  });
}

以上是我在工作中遇到的關(guān)于gcd的一些總結(jié)窃款,歡迎各路大神補(bǔ)充课兄,共同進(jìn)步!晨继!如果您看過(guò)文章覺(jué)得用得上烟阐,請(qǐng)給個(gè)贊謝謝!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末踱稍,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子悠抹,更是在濱河造成了極大的恐慌珠月,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件楔敌,死亡現(xiàn)場(chǎng)離奇詭異啤挎,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)卵凑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)庆聘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人勺卢,你說(shuō)我怎么就攤上這事伙判。” “怎么了黑忱?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵宴抚,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我甫煞,道長(zhǎng)菇曲,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任抚吠,我火速辦了婚禮常潮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘楷力。我一直安慰自己喊式,他們只是感情好孵户,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著垃帅,像睡著了一般延届。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贸诚,一...
    開(kāi)封第一講書(shū)人閱讀 49,111評(píng)論 1 285
  • 那天方庭,我揣著相機(jī)與錄音,去河邊找鬼酱固。 笑死械念,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的运悲。 我是一名探鬼主播龄减,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼班眯!你這毒婦竟也來(lái)了希停?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤署隘,失蹤者是張志新(化名)和其女友劉穎宠能,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年恤左,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了计呈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情伴箩,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布鄙漏,位于F島的核電站赛蔫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏泥张。R本人自食惡果不足惜呵恢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望媚创。 院中可真熱鬧渗钉,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至瘫怜,卻和暖如春术徊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鲸湃。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工赠涮, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人暗挑。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓笋除,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親炸裆。 傳聞我的和親對(duì)象是個(gè)殘疾皇子垃它,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1. GCD簡(jiǎn)介 什么是GCD呢?我們先來(lái)看看百度百科的解釋簡(jiǎn)單了解下概念 引自百度百科:Grand Centra...
    千尋_544f閱讀 359評(píng)論 0 0
  • 多線(xiàn)程 在iOS開(kāi)發(fā)中為提高程序的運(yùn)行效率會(huì)將比較耗時(shí)的操作放在子線(xiàn)程中執(zhí)行烹看,iOS系統(tǒng)進(jìn)程默認(rèn)啟動(dòng)一個(gè)主線(xiàn)程国拇,用...
    郭豪豪閱讀 2,587評(píng)論 0 4
  • GCD (Grand Central Dispatch) :iOS4 開(kāi)始引入,使用更加方便惯殊,程序員只需要將任務(wù)添...
    池鵬程閱讀 1,323評(píng)論 0 2
  • iOS多線(xiàn)程之GCD 什么是GCD GCD(grand central dispatch) 是 libdispat...
    comst閱讀 1,196評(píng)論 0 0
  • 原創(chuàng)文章 轉(zhuǎn)載請(qǐng)注明出處, 謝謝! (~ o ~)Y 本文思維導(dǎo)圖 GCD是什么 全稱(chēng)是 Grand Centra...
    Jimmy_P閱讀 4,659評(píng)論 10 67