iOS 多線程之GCD

GCD 簡(jiǎn)介
1胡陪、什么是GCD?
全稱(chēng)是 Grand Central Dispatch碍舍,純 C 語(yǔ)言編寫(xiě)柠座,提供了非常多強(qiáng)大的函數(shù)
2、GCD的優(yōu)勢(shì)是什么片橡?
GCD 是蘋(píng)果公司為多核的并行運(yùn)算提出的解決方案
GCD 會(huì)自動(dòng)利用更多的CPU內(nèi)核(比如雙核妈经、四核)
GCD 會(huì)自動(dòng)管理線程的生命周期(創(chuàng)建線程、調(diào)度任務(wù)、銷(xiāo)毀線程)
程序員只需要告訴 GCD 想要執(zhí)行什么任務(wù)吹泡,不需要編寫(xiě)任何線程管理代碼

串行并行录煤、同步異步

一、概念

  • 同步執(zhí)行(sync):在當(dāng)前線程中執(zhí)行任務(wù)荞胡,任務(wù)未執(zhí)行完時(shí)妈踊,會(huì)阻塞線程,不會(huì)開(kāi)辟線程

  • 異步執(zhí)行(async):另開(kāi)辟線程執(zhí)行任務(wù)泪漂,不會(huì)阻塞當(dāng)前線程廊营。

  • 串行隊(duì)列:按順序一個(gè)一個(gè)執(zhí)行,FIFO先進(jìn)先出原則

  • 并行隊(duì)列:可以讓多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行。(可以開(kāi)啟多個(gè)線程萝勤,并且同時(shí)執(zhí)行任務(wù))

一般使用中會(huì)有如下四種情況

  • 串行隊(duì)列,同步執(zhí)行:在當(dāng)前線程中,一個(gè)個(gè)執(zhí)行
  • 串行隊(duì)列,異步執(zhí)行:另開(kāi)辟一個(gè)線程,一個(gè)個(gè)執(zhí)行
  • 并行隊(duì)列,同步執(zhí)行:在當(dāng)前線程中,一個(gè)個(gè)執(zhí)行
  • 并行隊(duì)列,異步執(zhí)行:另開(kāi)辟多個(gè)線程,同時(shí)執(zhí)行

也就是說(shuō)串行同步和并行同步作用是一樣的露筒。

二、實(shí)例效果

結(jié)合代碼看一下效果
串行同步

/**
 串行隊(duì)列,同步執(zhí)行
 */
- (void)createSerialQueueWithSync {
    dispatch_queue_t serialQueue = dispatch_queue_create("com.neusoft", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(serialQueue, ^{
        NSLog(@"A==%@", [NSThread currentThread]);
    dispatch_sync(serialQueue, ^{
        NSLog(@"B==%@", [NSThread currentThread]);
    });
    dispatch_sync(serialQueue, ^{
        NSLog(@"C==%@", [NSThread currentThread]);
    });
    NSLog(@"D==%@", [NSThread currentThread]);
}

串行同步打印結(jié)果如下:


串行同步運(yùn)行結(jié)果

從結(jié)果中我們能看到敌卓,符合串行隊(duì)列的特征(一個(gè)一個(gè)執(zhí)行)慎式,符合同步執(zhí)行特征(在當(dāng)前線程執(zhí)行,并且阻塞了當(dāng)前線程)趟径。

串行異步

/**
 串行隊(duì)列,異步執(zhí)行
 */
- (void)createSerialQueueWithAsync {
    dispatch_queue_t serialQueue = dispatch_queue_create("com.neusoft", DISPATCH_QUEUE_SERIAL);
    dispatch_async(serialQueue, ^{
        NSLog(@"A==%@", [NSThread currentThread]);
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"B==%@", [NSThread currentThread]);
    });
    dispatch_async(serialQueue, ^{
        NSLog(@"C==%@", [NSThread currentThread]);
    });
    NSLog(@"D==%@", [NSThread currentThread]);
}

串行異步打印結(jié)果如下


串行異步運(yùn)行結(jié)果

從結(jié)果中可以看到瘪吏,符合串行隊(duì)列的特征(一個(gè)一個(gè)執(zhí)行),符合異步執(zhí)行特征(另開(kāi)辟線程蜗巧,且不阻塞當(dāng)前線程)掌眠。

并行同步

/**
 并行隊(duì)列,同步執(zhí)行
 */
- (void)createConcurrentQueueWithSync {
    dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.neusoft", DISPATCH_QUEUE_CONCURRENT);
    //    dispatch_queue_t conCurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//這個(gè)是全局并行隊(duì)列,一般并行任務(wù)都會(huì)加到這里面去
    
    dispatch_sync(conCurrentQueue, ^{
        NSLog(@"A==%@", [NSThread currentThread]);
    });
    dispatch_sync(conCurrentQueue, ^{
        NSLog(@"B==%@", [NSThread currentThread]);
    });
    dispatch_sync(conCurrentQueue, ^{
        NSLog(@"C==%@", [NSThread currentThread]);
    });
    NSLog(@"D==%@", [NSThread currentThread]);
}

并行同步打印結(jié)果如下


并行同步運(yùn)行結(jié)果

從結(jié)果可以看出,符合同步特征(在當(dāng)前線程幕屹,且阻塞當(dāng)前線程)蓝丙,但是并不清楚是否符合并行隊(duì)列的特征,并行隊(duì)列的效果需要異步執(zhí)行才能看出來(lái)望拖,并行同步整體的效果和串行同步相同渺尘。

并行異步

/**
 并行隊(duì)列,異步執(zhí)行
 */
- (void)createConcurrentQueueWithAsync {
    dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.neusoft", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"A==%@", [NSThread currentThread]);
    });
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"B==%@", [NSThread currentThread]);
    });
    dispatch_async(conCurrentQueue, ^{
        NSLog(@"C==%@", [NSThread currentThread]);
    });
    NSLog(@"D==%@", [NSThread currentThread]);
}

并行異步打印結(jié)果如下


并行異步運(yùn)行結(jié)果

從結(jié)果中可以看出,符合并行隊(duì)列特征(可以并發(fā)執(zhí)行線程任務(wù))说敏,符合異步執(zhí)行特征(另開(kāi)辟線程鸥跟,且不阻塞當(dāng)前線程)。

//全局并發(fā)隊(duì)列
dispatch_get_global_queue
//主線程--串行隊(duì)列
dispatch_get_main_queue()

這兩個(gè)隊(duì)列在系統(tǒng)剛啟動(dòng)時(shí)就創(chuàng)建好的隊(duì)列像云,一般不建議使用全局并發(fā)隊(duì)列锌雀,因?yàn)樵谌植l(fā)隊(duì)列中也會(huì)執(zhí)行系統(tǒng)的任務(wù)蚂夕,對(duì)于調(diào)試和業(yè)務(wù)剝離等造成影響迅诬。

死鎖

死鎖總結(jié)一句話:串行隊(duì)列(當(dāng)然也包括主隊(duì)列)中向該隊(duì)列添加同步任務(wù),必定導(dǎo)致死鎖婿牍。

兩個(gè)死鎖案例幫助理解這句話侈贷,
例 1:

- (void)test1 {
    //1,5,2,造成死鎖,
    //1俏蛮,5撑蚌,2,async是異步搏屑,所以會(huì)開(kāi)辟線程争涌,當(dāng)然開(kāi)辟線程需要耗時(shí),所以5在先辣恋,2在后
    //為什么會(huì)造成死鎖亮垫?因?yàn)殛?duì)列中加入任務(wù)的順序是2、4伟骨、3饮潦,按照隊(duì)列的FIFO原則,理應(yīng)4執(zhí)行完再執(zhí)行3携狭,但執(zhí)行完2遇到了sync同步函數(shù)继蜡,需要阻塞線程,4需要等待3執(zhí)行完再執(zhí)行逛腿,造成了互相等待即死鎖稀并。
    NSLog(@"1==%@", [NSThread currentThread]);
    dispatch_queue_t queue = dispatch_queue_create("com.serial", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        NSLog(@"2==%@", [NSThread currentThread]);
        dispatch_sync(queue, ^{
            NSLog(@"3==%@", [NSThread currentThread]);
        });
        NSLog(@"4==%@", [NSThread currentThread]);
    });
    NSLog(@"5==%@", [NSThread currentThread]);
}

輸出結(jié)果是 1、5单默、2稻轨,然后發(fā)生死鎖崩潰,執(zhí)行過(guò)程如下

  1. 主隊(duì)列按順序先執(zhí)行 test 代碼塊簡(jiǎn)稱(chēng) A雕凹,由于dispatch_async(queue是異步串行的另一個(gè)隊(duì)列殴俱,不阻塞當(dāng)前隊(duì)列,所以這里先執(zhí)行了 A 的 1 和 5枚抵。
  2. 來(lái)到dispatch_async(queue代碼塊线欲,另起了新的線程處理隊(duì)列 queue,已知 queue 里面是(2汽摹、dispatch_sync(queue李丰、4)代碼塊簡(jiǎn)稱(chēng) B。
  3. 執(zhí)行 B 的 2
  4. 執(zhí)行dispatch_sync(queue時(shí)發(fā)現(xiàn)這是同步函數(shù)逼泣,需要阻塞隊(duì)列 queue趴泌,在當(dāng)前線程執(zhí)行dispatch_sync(queue代碼塊,但這個(gè)代碼塊的要在 queue 中執(zhí)行拉庶,而 queue 已經(jīng)被阻塞了嗜憔,造成了互相等待,導(dǎo)致死鎖氏仗。

例 2:

- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"deadlock");
    });
}

同步對(duì)于任務(wù)是立即執(zhí)行的吉捶,當(dāng)把任務(wù)放進(jìn)主隊(duì)列時(shí),它會(huì)立即執(zhí)行,只有執(zhí)行完這個(gè)任務(wù)呐舔,viewDidLoad才會(huì)繼續(xù)執(zhí)行币励。
viewDidLoad和任務(wù)都在主隊(duì)列上,根據(jù)隊(duì)列的先入先出原則珊拼,需要先執(zhí)行完viewDidLoad再執(zhí)行任務(wù)食呻,造成了互相等待,導(dǎo)致死鎖澎现。

柵欄函數(shù)barrier

一搁进、概念
dispatch_barrier_async加入到自定義的并行隊(duì)列(不能是全局global隊(duì)列)時(shí),程序會(huì)先執(zhí)行隊(duì)列中barrier之前的任務(wù),再執(zhí)行barrier的任務(wù),最后再執(zhí)行隊(duì)列中barrier之后的任務(wù)。

二昔头、實(shí)例
直接上代碼
實(shí)例一饼问、應(yīng)用了dispatch_barrier_async的隊(duì)列中,線程的執(zhí)行順序揭斧。

- (void)createBarrierAsync {
    dispatch_queue_t queue = dispatch_queue_create("liufeng", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"start==%@", [NSThread currentThread]);
    
    dispatch_async(queue, ^{
        NSLog(@"A==%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"B==%@", [NSThread currentThread]);
    });
    dispatch_barrier_async(queue, ^{
        NSLog(@"barrier_async==%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"C==%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"D==%@", [NSThread currentThread]);
    });
    NSLog(@"end==%@", [NSThread currentThread]);
}

控制臺(tái)打印效果如下


柵欄函數(shù)的打印結(jié)果

從打印結(jié)果我們可以看到莱革,程序會(huì)先執(zhí)行隊(duì)列中barrier之前的任務(wù),再執(zhí)行barrier的任務(wù),最后再執(zhí)行隊(duì)列中barrier之后的任務(wù)。

實(shí)例二讹开、從網(wǎng)絡(luò)加載圖片盅视,并給圖片加上水印后顯示到屏幕上

- (void)testPic {
    dispatch_queue_t concurrentQueue = dispatch_queue_create("com.waterImage", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(concurrentQueue, ^{
        NSString *logoStr = @"https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3351002169,4211425181&fm=27&gp=0.jpg";
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:logoStr]];
        UIImage *image = [UIImage imageWithData:data];
        [self.mArray addObject:image];
    });
    
    dispatch_async(concurrentQueue, ^{
        NSString *logoStr = @"https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3033952616,135704646&fm=27&gp=0.jpg";
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:logoStr]];
        UIImage *image = [UIImage imageWithData:data];
        [self.mArray addObject:image];
    });
    
    __block UIImage *newImage = nil;
    dispatch_barrier_async(concurrentQueue, ^{
        
        for (int i = 0; i<self.mArray.count; i++) {
            UIImage *waterImage = self.mArray[i];
            newImage = [LFPrintImageTool printText:@"小姑娘還不睡呀?" onImage:waterImage];
        }
    });
    
    
    dispatch_async(concurrentQueue, ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            self.imageView.image = newImage;
        });
    });
}

模擬器顯示如圖所示


柵欄函數(shù)應(yīng)用在圖片加水印

這個(gè)從結(jié)果看不出來(lái)什么旦万,主要看代碼闹击,我們程序的步驟是這樣的,先將圖片從網(wǎng)絡(luò)獲取下來(lái)成艘,才能給它加水印赏半,最后顯示到屏幕上,柵欄函數(shù)相當(dāng)于阻塞了當(dāng)前線程淆两。

注意:柵欄函數(shù)必須是自定義的并發(fā)隊(duì)列才有效断箫,且必須是同一隊(duì)列中的線程才有效。

調(diào)度組

一秋冰、概念
在調(diào)度組內(nèi)的線程都執(zhí)行完畢后仲义,dispatch_notify函數(shù)會(huì)觸發(fā)回調(diào)。

二剑勾、實(shí)例
應(yīng)用場(chǎng)景:
一個(gè)業(yè)務(wù)需要開(kāi)啟N個(gè)異步線程埃撵,但是后續(xù)操作,需要依賴(lài)N個(gè)線程返回的數(shù)據(jù)完成操作虽另。
直接上代碼
實(shí)例一

- (void)createGroupQueue {
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_async(group, queue, ^{
        NSLog(@"A---%@", [NSThread currentThread]);
    });
    
    dispatch_group_async(group, queue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"B---%@", [NSThread currentThread]);
        }
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"C---%@", [NSThread currentThread]);
    });
    
    dispatch_notify(group, queue, ^{
        NSLog(@"隊(duì)列組任務(wù)執(zhí)行完畢");
    });
}

調(diào)度組執(zhí)行結(jié)果如下

調(diào)度組執(zhí)行結(jié)果

從結(jié)果中可以看出暂刘,符合預(yù)期,調(diào)度組內(nèi)的線程都執(zhí)行完畢后洲赵,dispatch_notify函數(shù)會(huì)觸發(fā)回調(diào)鸳惯。

實(shí)例二

- (void)test2 {
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"A---%@", [NSThread currentThread]);
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"B---%@", [NSThread currentThread]);
        }
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"C---%@", [NSThread currentThread]);
        dispatch_group_leave(group);
    });
    
    dispatch_notify(group, queue, ^{
        NSLog(@"隊(duì)列組任務(wù)執(zhí)行完畢");
    });
}

上面這個(gè)實(shí)例是以進(jìn)組出組的方式實(shí)現(xiàn)調(diào)度。
dispatch_group_enter(group);
dispatch_group_leave(group);
進(jìn)組出組的方式類(lèi)似于信號(hào)量叠萍,內(nèi)部有一個(gè)signal芝发,enter加1,leave減1苛谷,它們總是成對(duì)出現(xiàn)辅鲸,當(dāng)signal為0時(shí),表示調(diào)度組里面的任務(wù)都執(zhí)行完了腹殿。

信號(hào)量

一独悴、作用
可以控制并發(fā)隊(duì)列的最大并發(fā)數(shù),當(dāng)創(chuàng)建的信號(hào)量限制為1時(shí)锣尉,可以達(dá)到鎖的效果刻炒。

二、概念
信號(hào)量,一般用來(lái)線程并發(fā)數(shù)量自沧,信號(hào)量為幾坟奥,線程最大并發(fā)數(shù)就是幾
//創(chuàng)建信號(hào)量,參數(shù):信號(hào)量的初值拇厢,當(dāng)信號(hào)量小于0時(shí)阻塞當(dāng)前線程
dispatch_semaphore_create(信號(hào)量值)

//等待降低信號(hào)量
dispatch_semaphore_wait(信號(hào)量爱谁,等待時(shí)間)

//提高信號(hào)量
dispatch_semaphore_signal(信號(hào)量)

三、實(shí)例

- (void)createSemaphoreQueue {
    //create的value表示孝偎,最多幾個(gè)資源可訪問(wèn)
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //任務(wù)1
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 1");
        sleep(1);
        NSLog(@"complete task 1");
        dispatch_semaphore_signal(semaphore);
    });
    //任務(wù)2
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 2");
        sleep(1);
        NSLog(@"complete task 2");
        dispatch_semaphore_signal(semaphore);
    });
    //任務(wù)3
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"run task 3");
        sleep(1);
        NSLog(@"complete task 3");
        dispatch_semaphore_signal(semaphore);
    });
}

控制臺(tái)打印效果如下


信號(hào)量測(cè)試.png

再次執(zhí)行效果如下


信號(hào)量測(cè)試

可以看到访敌,始終都是task1和task2先執(zhí)行完,信號(hào)量經(jīng)過(guò)dispatch_semaphore_signal增加以后衣盾,task3才能執(zhí)行寺旺,結(jié)論就是不論并發(fā)隊(duì)列中有多少任務(wù)等待執(zhí)行,同一時(shí)間只允許兩個(gè)任務(wù)執(zhí)行势决。

總結(jié)

以上就是GCD的基本使用迅涮,在很多大型的底層框架中,很多使用的都是NSOperation徽龟,因?yàn)?code>NSOperation更加靈活叮姑,開(kāi)發(fā)者可以更好的監(jiān)控線程的生命周期以及做處理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末据悔,一起剝皮案震驚了整個(gè)濱河市传透,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌极颓,老刑警劉巖朱盐,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異菠隆,居然都是意外死亡兵琳,警方通過(guò)查閱死者的電腦和手機(jī)狂秘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)躯肌,“玉大人者春,你說(shuō)我怎么就攤上這事∏迮” “怎么了钱烟?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)嫡丙。 經(jīng)常有香客問(wèn)我拴袭,道長(zhǎng),這世上最難降的妖魔是什么曙博? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任拥刻,我火速辦了婚禮,結(jié)果婚禮上父泳,老公的妹妹穿的比我還像新娘泰佳。我一直安慰自己,他們只是感情好尘吗,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布逝她。 她就那樣靜靜地躺著,像睡著了一般睬捶。 火紅的嫁衣襯著肌膚如雪黔宛。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,482評(píng)論 1 302
  • 那天擒贸,我揣著相機(jī)與錄音臀晃,去河邊找鬼。 笑死介劫,一個(gè)胖子當(dāng)著我的面吹牛徽惋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播座韵,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼险绘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了誉碴?” 一聲冷哼從身側(cè)響起宦棺,我...
    開(kāi)封第一講書(shū)人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎黔帕,沒(méi)想到半個(gè)月后代咸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡成黄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年呐芥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逻杖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡思瘟,死狀恐怖荸百,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情潮太,我是刑警寧澤管搪,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布虾攻,位于F島的核電站铡买,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏霎箍。R本人自食惡果不足惜奇钞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望漂坏。 院中可真熱鬧景埃,春花似錦、人聲如沸顶别。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)驯绎。三九已至完慧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間剩失,已是汗流浹背屈尼。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拴孤,地道東北人脾歧。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像演熟,于是被迫代替她去往敵國(guó)和親鞭执。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

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

  • 多線程 在iOS開(kāi)發(fā)中為提高程序的運(yùn)行效率會(huì)將比較耗時(shí)的操作放在子線程中執(zhí)行芒粹,iOS系統(tǒng)進(jìn)程默認(rèn)啟動(dòng)一個(gè)主線程蚕冬,用...
    郭豪豪閱讀 2,597評(píng)論 0 4
  • GCD (Grand Central Dispatch) :iOS4 開(kāi)始引入,使用更加方便是辕,程序員只需要將任務(wù)添...
    池鵬程閱讀 1,332評(píng)論 0 2
  • 繼上一篇說(shuō)到的NSTread之后 本文主要分享下GCD的一些總結(jié)主要是按一下幾點(diǎn)進(jìn)行: GCD是什么? GCD任務(wù)...
    土鱉不土閱讀 1,866評(píng)論 2 8
  • 1. GCD簡(jiǎn)介 什么是GCD呢囤热?我們先來(lái)看看百度百科的解釋簡(jiǎn)單了解下概念 引自百度百科:Grand Centra...
    千尋_544f閱讀 365評(píng)論 0 0
  • 每個(gè)人總有自己不想觸碰的地方,但總會(huì)有一些人能讓你不受控制的走出自己的舒適區(qū)获三。不管初衷是否真誠(chéng)旁蔼,我與酒兒在一起的時(shí)...
    自此不飲酒閱讀 586評(píng)論 12 7