iOS多線程雜論

最近這段時間忙忘記了總結(jié)自己的所得以及所獲了苛骨,由于為年后工作座準備今天看了看多線程罚缕,那么下面為大家?guī)砦业乃屑八冒伞?/p>

iOS多線程的分布

(1) NSThread

(2) NSOperation

(3) GCD


現(xiàn)在對下面三個進行一個個的分析盆昙,希望那里說得不對的地方希望簡友們幫我指點一二。

1,NSThread

優(yōu)點:NSThread相對比較輕量級
缺點:需要自己管理線程生命周期笑陈,線程同步笛臣,線程同步對數(shù)據(jù)加鎖有一定的系統(tǒng)開銷;


NSThread 實現(xiàn)的三種方式:

1尸饺,
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadInitDoSomething) object:nil]; [thread start];
這種方法需要手動開啟線程缭付。
2辰斋,
[NSThread detachNewThreadSelector:@selector(threadDetachDosomething) toTarget:self withObject:nil];
這種便利構(gòu)造的方法不需要手動開啟
3蓬网,
[self performSelectorInBackground:@selector(backGround) withObject:nil];
這種方式是NSObject對象自帶的開啟后臺線程的方法诞丽。

2,NSOperation

優(yōu)點:
不需要手動關(guān)系線程,可以把精力放在自己要執(zhí)行的操作上面迹栓,NSOperation我們一般使用它的子類NSInvocationOperation NSBlockOperation或者繼承NSOperation的自定義任務(wù)掉分,我們經(jīng)常將任務(wù)和隊列NSOperationQueue進行搭配使用,一個對象一個任務(wù)克伊,更利于任務(wù)的管理酥郭,還有一個優(yōu)點在于可以明確的確定依賴關(guān)系
缺點:
他是一個OC對象,那么相對于C函數(shù)效率要低答毫,而且基于GCD褥民,那么GCD將提供比他更加全面的功能;


NSOperation 的使用:

1,
NSInvocationOperation *incocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationDoSomething) object:nil]; [incocation start];
這種方式利用的Target-Action的設(shè)計模式洗搂,讓響應(yīng)者去執(zhí)行任務(wù)。
2载弄,
NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"%d, %@", [NSThread isMainThread], [NSThread currentThread]); }]; [block start];
這種方式利用OC里面經(jīng)典的語法block(語法塊)耘拇。但是和上者一樣,如果單獨使用NSOperation的子類對象必須手動的開啟任務(wù)宇攻。
3惫叛,
//NSOperationQueue里面只有串行的時候線程優(yōu)先級才是可行的 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; //最大并發(fā)量,如果最大病發(fā)量為1時逞刷,那么隊列里面的任務(wù)將串行嘉涌,也就是執(zhí)行完一個任務(wù)才能執(zhí)行下一個,如果不為1夸浅,那就是并發(fā)進行仑最。 queue.maxConcurrentOperationCount = 1;

//添加block塊任務(wù) NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"--0--%d, %@", [NSThread isMainThread], [NSThread currentThread]); }]; //設(shè)置任務(wù)的優(yōu)先級,只有隊列為串行的時候優(yōu)先級才能起到絕對的作用 [block setQueuePriority:NSOperationQueuePriorityVeryHigh]; NSBlockOperation *block1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"--1--%d, %@", [NSThread isMainThread], [NSThread currentThread]); }]; [block1 setQueuePriority:NSOperationQueuePriorityNormal]; NSBlockOperation *block2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"--2--%d, %@", [NSThread isMainThread], [NSThread currentThread]); }]; [block2 setQueuePriority:NSOperationQueuePriorityVeryLow]; NSBlockOperation *block3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"--3--%d, %@", [NSThread isMainThread], [NSThread currentThread]); }]; [block3 setQueuePriority:NSOperationQueuePriorityVeryHigh];

//設(shè)置以來關(guān)系帆喇,只有執(zhí)行完block之后才會去執(zhí)行block1警医,這叫做任務(wù)block1依賴于block,在項目開發(fā)中經(jīng)常用到
[block1 addDependency:block];
//添加任務(wù),任務(wù)為NSOperation對象的子類,添加到任務(wù)隊列中之后會自動去執(zhí)行预皇,不需要start侈玄;
[queue addOperation:block];
[queue addOperation:block1];
[queue addOperation:block2];
[queue addOperation:block3];`

NSOperationQueue在開發(fā)中經(jīng)常會使用到,比如我們做多任務(wù)下載的時候吟温,使用自定義NSOperation子類和NSOperationQueue結(jié)合使用序仙,每個NSOperation對象是一個任務(wù),而NSOperationQueue卻完美的擔(dān)任了任務(wù)關(guān)系器的角色鲁豪。抽時間會把demo上傳到github上面诱桂,請及大家及時關(guān)注。任務(wù)之間的依賴也是NSOperation的一大完美特征呈昔。

3挥等,GCD(重點介紹)

GCD簡介

GCD-(Grand Central Dispatch)是Apple公司開發(fā)的一種技術(shù)。這種技術(shù)可以在多核硬件中并發(fā)處理多個任務(wù)堤尾。也可以說肝劲,GCD是多線程的一種擴展和替代技術(shù)。GCD 在Mac OS x 10.6 和 IOS 4.0 以后開始支持郭宝。

GCD的特點

1.GCD可以在充分利用多核硬件并發(fā)處理多個任務(wù)辞槐。也就是說,效率高粘室。
2.GCD 的API提供了很多同步榄檬,異步,分組等正對多任務(wù)衔统,同步鹿榜,異步的操作。也就是一種比多線程還要牛X寫的技術(shù)锦爵。
3.使用GCD我們可以更容易的利用多核處理器并行處理任務(wù)舱殿。
4.GCD 使用后不用程序去管理線程的開閉,GCD會在系統(tǒng)層面上去動態(tài)檢測系統(tǒng)狀態(tài)险掀,開閉線程沪袭。

我在學(xué)習(xí)GCD的時候掉進的誤區(qū)

看了很多網(wǎng)上的博客,寫的都特別好樟氢,但是我在使用的時候還是遇到了一些問題冈绊,比如同步和異步與串行和并行之間總是分不清,并行和并發(fā)我一直以為是一個概念之類的問題埠啃,現(xiàn)在我先對這兩個問題點將我的理解分享給大家死宣,


串行和并行與同步異步執(zhí)行的問題,串行并行決定了對列中任務(wù)的執(zhí)行規(guī)則(循序)串行隊列隊列里面的任務(wù)循序執(zhí)行霸妹,并行隊列根據(jù)系統(tǒng)資源而定十电,沒有一定的規(guī)則。并且給我們的感覺是多個任務(wù)同時執(zhí)行。異步和同步只是GCD里面對任務(wù)block的處理問題鹃骂,同步忽略block代碼循序執(zhí)行台盯,異步卻是正常的block邏輯,及某一時刻進行回調(diào)畏线,而且是先進隊列咧線回調(diào)(在串行隊列里)静盅。


并行和并發(fā),由于現(xiàn)在多核cpu的出現(xiàn)出現(xiàn)了并行這個說話寝殴,及一個cpu核心處理一個任務(wù)蒿叠,兩個任務(wù)或者多個任務(wù)同時執(zhí)行,但是并發(fā)卻是同一個cpu核心來回調(diào)度蚣常,但是因為時間極短的來回調(diào)度市咽,給我們造成了錯誤的感覺兩個任務(wù)同時執(zhí)行,其實是執(zhí)行完這個任務(wù)的某一部分之后將cpu調(diào)度到另一個任務(wù)抵蚊。來回調(diào)度的一個過程

我心中的GCD

經(jīng)過一些行業(yè)面試人員的反饋施绎,GCD是多線程里面被問及最多的,所以在GCD里面我投入了更多的精力贞绳,下面我們一起走入我的GCD時間吧谷醉,在這里如果有做得不足的地方希望大家可以給我一些見解,共同進步冈闭。

GCD隊列方式

主隊列

dispatch_queue_t queue = dispatch_get_main_queue();
主隊列是串行隊列,任務(wù)是從上到下一個一個執(zhí)行的俱尼。
dispatch_async(queue, ^{ NSLog(@"這是第一個任務(wù),當(dāng)前線程是:%@, 是否主線程 :%d ", [NSThread currentThread], [[NSThread currentThread] isMainThread]); });
上面這個函數(shù)意思是在主隊列里面異步執(zhí)行block里面的任務(wù)萎攒;

dispatch_sync(queue, ^{ NSLog(@"這是第一個任務(wù)遇八,當(dāng)前線程是:%@, 是否主線程 :%d ", [NSThread currentThread], [[NSThread currentThread] isMainThread]); });
上面這一行代碼意思是在主線成中同步執(zhí)行block塊里面的任務(wù),但是這樣做會讓主線程假死躺酒,無法執(zhí)行任何操作押蚤,且不論你在任何隊列里面同步執(zhí)行一系列的任務(wù),都會在主線程去執(zhí)行羹应。但是不會出現(xiàn)主線程假死,所以同步我們很少去用次屠。(GCD里面注意的地方)

到了這里索性將同步執(zhí)行任務(wù)和異步執(zhí)行任務(wù)給大家解釋一下吧园匹,同步執(zhí)行任務(wù)一定就是串行,異步執(zhí)行任務(wù)并不一定說并行劫灶,跟我們的網(wǎng)絡(luò)請求有些類似裸违,同步及循序結(jié)構(gòu),代碼一行一行的往下執(zhí)行本昏,異步及回調(diào)思想供汛,某一時刻再執(zhí)行block塊里面的任務(wù)。

全局隊列

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
全局隊列是并行隊列,任務(wù)時并行的,充分利用了現(xiàn)在多核cpu的優(yōu)勢怔昨,第一個參數(shù)為隊列的優(yōu)先級雀久,第二參數(shù)為蘋果預(yù)留參數(shù)現(xiàn)在沒有實際作用我們一般填寫0。
dispatch_async(queue, ^{ NSLog(@"這是第一個任務(wù)趁舀,當(dāng)前線程是:%@, 是否主線程 :%d ", [NSThread currentThread], [[NSThread currentThread] isMainThread]); });
如果將一系列的任務(wù)加到全局隊列里面時赖捌,任務(wù)就并發(fā)執(zhí)行,從而沒發(fā)預(yù)知那個任務(wù)先完成矮烹。

自定義隊列

dispatch_queue_t queue = dispatch_queue_create("com.zouhao", DISPATCH_QUEUE_CONCURRENT);
自定義隊列可以是并行的也可以是串行的越庇,第一個參數(shù)是隊列的名稱也可以稱之為標示吧,第二個參數(shù)是決定隊列是串行還是并行的DISPATCH_QUEUE_CONCURRENT代表并行 DISPATCH_QUEUE_SERIAL代表串行

dispatch_async(queue, ^{ NSLog(@"這是第一個任務(wù)奉狈,當(dāng)前線程是:%@, 是否主線程 :%d ", [NSThread currentThread], [[NSThread currentThread] isMainThread]); });
這個意思和上面兩個意思基本一樣卤唉,在自定隊列里面加入了一個任務(wù),任務(wù)就是block里面的業(yè)務(wù)仁期。
那么隊列就到這里吧桑驱,下面我們一起來看看GCD里面的一些比較常規(guī)的函數(shù)吧。

GCD延時執(zhí)行蟀拷,只執(zhí)行一次碰纬,重復(fù)執(zhí)行,分組任務(wù)问芬,Barrier悦析,函數(shù)指針

這是GCD里面的一些比較常規(guī)的使用方法,但是很多簡友們在開發(fā)過程中此衅,往往用一些奇怪的邏輯來避免使用這些方法强戴,導(dǎo)致沒有見過,或者使用過挡鞍。下面我們一起來看看這些方式到底是干嘛用的吧骑歹。

GCD延時執(zhí)行

//第一個參數(shù)是從現(xiàn)在開始,第二個參數(shù)是時間墨微, dispatch_time_t delayInNanoSeconds =dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); //推遲兩納秒執(zhí)行 dispatch_queue_t concurrentQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //第一個參數(shù)只延遲時間道媚,第二個參數(shù)是在那個隊列里,第三個是任務(wù)翘县, dispatch_after(delayInNanoSeconds, concurrentQueue, ^(void){ NSLog(@"Grand Center Dispatch!"); });

GCD重復(fù)執(zhí)行

//有時候項目需求我們重復(fù)執(zhí)行一個方法多次最域,比如我們常見的項目了面的倒計時的計時器,很多都是用GCD實現(xiàn)的锈麸。 dispatch_queue_t queue = dispatch_queue_create("com.zouhao", DISPATCH_QUEUE_SERIAL); dispatch_apply(3, queue, ^(size_t index) { NSLog(@"%zu, %@", index, [NSThread currentThread]); });
這里我們看看dispatch_apply函數(shù)的幾個參數(shù)分別是什么意思镀脂,第一個參數(shù)是重復(fù)執(zhí)行多少次,第二個參數(shù)是在那個隊列里面執(zhí)行任務(wù)忘伞,第三個是任務(wù)薄翅,block里面的參數(shù)意思是第幾次執(zhí)行沙兰。

GCD只執(zhí)行一次

//只執(zhí)行一次,單例對象創(chuàng)建的時候經(jīng)常需要用到它 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"只會執(zhí)行一次"); });
這里看看diapatch_once函數(shù)后面跟著兩個參數(shù)翘魄,第一個參數(shù)傳了一個地址鼎天,第二個參數(shù)是任務(wù),當(dāng)執(zhí)行到block塊里面時熟丸,就會向第一個參數(shù)指針指向的地址寫入信息训措,當(dāng)下一次在執(zhí)行這個代碼時發(fā)現(xiàn)內(nèi)存已經(jīng)被寫入過就不會再執(zhí)行block了。

只執(zhí)行一次在單例里面使用比較多光羞,但是我們自己實現(xiàn)單例構(gòu)造方法時绩鸣,Class objcet = [[Class alloc] init];將他放在dispatch_once的block塊內(nèi),然后覺得自己的單例完美了纱兑,其實不然呀闻,如果我們在外面調(diào)用init方法還是新對象,那么我們一般回去控制 initialize 在這個方法里面控制潜慎,詳細的可以去百度捡多。

分組任務(wù)

有時候我們開發(fā)的時候或許有需求需要講隊列里面的一些任務(wù)加到一個分組里面進行管理。當(dāng)分組里面的任務(wù)執(zhí)行完之后我們可能需要做一些其他的邏輯铐炫。

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(@"第一個任務(wù) %d, %@", [NSThread isMainThread], [NSThread currentThread]); }); dispatch_group_async(group, queue, ^{ NSLog(@"第二個任務(wù) %d, %@", [NSThread isMainThread], [NSThread currentThread]); });
這樣我們就講所有的隊列里面的任務(wù)用分組進行管理了,這個的隊列可以使多個倒信,當(dāng)分組里面的任務(wù)執(zhí)行完成之后我們用到了一個新的函數(shù)

//這個通知不能寫在還所有任務(wù)之上科贬,必須保證先在隊列里面加入任務(wù)之后他才能夠用,說簡單的就是如果隊列里面沒有任務(wù)的時候他就會默認隊列任務(wù)被執(zhí)行完然后走通知 dispatch_group_notify(group, queue, ^{ NSLog(@"分組里面的最后一個任務(wù)了鳖悠!"); });
但是這個任務(wù)不能第一個加到分組里榜掌,要不然這個時候分組為空,默認所有任務(wù)都執(zhí)行完乘综,直接對調(diào)通知的這個block憎账。

GCD Barrier

當(dāng)我們操作數(shù)據(jù)庫的時候經(jīng)常分為寫與讀兩個過程,但是多線程操作往往存在一定的問題卡辰,比如我在讀的時候正好在寫入胞皱,這樣無法保證數(shù)據(jù)的可行性,這個時候當(dāng)我們寫入的時候要阻斷讀寫的線程九妈,讓其處于等候狀態(tài)朴恳。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^{ NSLog(@"這是第一個讀取數(shù)據(jù)的任務(wù)。允蚣。。線程是:%@呆贿, 是否主線程:%d", [NSThread currentThread], [[NSThread currentThread] isMainThread]); }); dispatch_async(queue, ^{ NSLog(@"這是第二個讀取數(shù)據(jù)的任務(wù)嚷兔。森渐。。線程是:%@冒晰, 是否主線程:%d", [NSThread currentThread], [[NSThread currentThread] isMainThread]); }); dispatch_async(queue, ^{ NSLog(@"這是第三個任務(wù)讀取數(shù)據(jù)的任務(wù)同衣。。壶运。線程是:%@耐齐, 是否主線程:%d", [NSThread currentThread], [[NSThread currentThread] isMainThread]); }); dispatch_barrier_async(queue, ^{ NSLog(@"你哥哥給數(shù)據(jù)庫里面寫東西,不要打擾我"); }); dispatch_async(queue, ^{ NSLog(@"這是第四個讀取數(shù)據(jù)的任務(wù)蒋情。埠况。。線程是:%@棵癣, 是否主線程:%d", [NSThread currentThread], [[NSThread currentThread] isMainThread]); }); dispatch_async(queue, ^{ NSLog(@"這是第五個讀取數(shù)據(jù)的任務(wù)辕翰。。狈谊。線程是:%@喜命, 是否主線程:%d", [NSThread currentThread], [[NSThread currentThread] isMainThread]); }); dispatch_async(queue, ^{ NSLog(@"這是第六個任務(wù)讀取數(shù)據(jù)的任務(wù)。河劝。壁榕。線程是:%@, 是否主線程:%d", [NSThread currentThread], [[NSThread currentThread] isMainThread]); });
很明顯的可以看出來雖然是異步執(zhí)行赎瞎,但是在dispatch_barrierh函數(shù)上面的方法執(zhí)行之后dispatch_barrierh下面的的任務(wù)講處于等候狀態(tài)牌里,知道dispatch_barrierh函數(shù)里面的任務(wù)完成之后再去執(zhí)行。

GCD函數(shù)指針

我們在調(diào)用GCD函數(shù)的時候發(fā)現(xiàn)很多方法很相似煎娇,只是函數(shù)名多了_f這就是我們的函數(shù)指針二庵,下面我們一起看看有哪些

// dispatch_async_f(dispatch_get_main_queue(), "haha", func); // dispatch_sync_f(<#dispatch_queue_t queue#>, <#void *context#>, <#dispatch_function_t work#>) // dispatch_after_f(<#dispatch_time_t when#>, <#dispatch_queue_t queue#>, <#void *context#>, <#dispatch_function_t work#>) // dispatch_apply_f(<#size_t iterations#>, <#dispatch_queue_t queue#>, <#void *context#>, <#void (*work)(void *, size_t)#>) // dispatch_barrier_async_f(<#dispatch_queue_t queue#>, <#void *context#>, <#dispatch_function_t work#>) // dispatch_barrier_sync_f(<#dispatch_queue_t queue#>, <#void *context#>, <#dispatch_function_t work#>) // dispatch_group_async_f(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#void *context#>, <#dispatch_function_t work#>) // dispatch_group_notify_f(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#void *context#>, <#dispatch_function_t work#>) // dispatch_once_f(<#dispatch_once_t *predicate#>, <#void *context#>, <#dispatch_function_t function#>) // dispatch_set_finalizer_f(<#dispatch_object_t object#>, <#dispatch_function_t finalizer#>)
我們在實現(xiàn)對應(yīng)的函數(shù)的時候一定要注意,函數(shù)的返回值為void缓呛,參數(shù)是void * 類型的催享,

為什么我們明明有了直接的函數(shù)調(diào)用還要出現(xiàn)函數(shù)指針實現(xiàn)任務(wù)體呢?很明顯block是OC里面的語法塊哟绊,但是函數(shù)確是C語言里面的語法因妙,這樣來看函數(shù)指針這種模式必然比較低層,那么效率必然會比block這種模式要高票髓,但是GCD本生封裝已經(jīng)很完美攀涵,如果想單單通過講block換成函數(shù)指針提高很多的效率是辦不到的,只是在一些要求精細的項目里面會祈禱細微的提高效率的作用洽沟。

今天的多線程雜論就到這里了以故,如果大家有什么好的見解可以給我反饋,大家好共同的進步裆操。下一篇為 XMPP實戰(zhàn)怒详,我將會講這些demo全部上傳到Github炉媒,在下一期的時候我會公布Github 的鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市昆烁,隨后出現(xiàn)的幾起案子吊骤,更是在濱河造成了極大的恐慌,老刑警劉巖静尼,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件白粉,死亡現(xiàn)場離奇詭異,居然都是意外死亡鼠渺,警方通過查閱死者的電腦和手機鸭巴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來系冗,“玉大人奕扣,你說我怎么就攤上這事≌凭矗” “怎么了惯豆?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長奔害。 經(jīng)常有香客問我楷兽,道長,這世上最難降的妖魔是什么华临? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任芯杀,我火速辦了婚禮,結(jié)果婚禮上雅潭,老公的妹妹穿的比我還像新娘揭厚。我一直安慰自己,他們只是感情好扶供,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布筛圆。 她就那樣靜靜地躺著,像睡著了一般椿浓。 火紅的嫁衣襯著肌膚如雪太援。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天扳碍,我揣著相機與錄音提岔,去河邊找鬼。 笑死笋敞,一個胖子當(dāng)著我的面吹牛碱蒙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播夯巷,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼振亮,長吁一口氣:“原來是場噩夢啊……” “哼巧还!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起坊秸,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎澎怒,沒想到半個月后褒搔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡喷面,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年星瘾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惧辈。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡琳状,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盒齿,到底是詐尸還是另有隱情念逞,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布边翁,位于F島的核電站翎承,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏符匾。R本人自食惡果不足惜叨咖,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望啊胶。 院中可真熱鬧甸各,春花似錦、人聲如沸焰坪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽琳彩。三九已至誊酌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間露乏,已是汗流浹背碧浊。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瘟仿,地道東北人箱锐。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像劳较,于是被迫代替她去往敵國和親驹止。 傳聞我的和親對象是個殘疾皇子浩聋,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

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

  • 1. GCD簡介 什么是GCD呢?我們先來看看百度百科的解釋簡單了解下概念 引自百度百科:Grand Centra...
    千尋_544f閱讀 359評論 0 0
  • 一臊恋、前言 上一篇文章iOS多線程淺匯-原理篇中整理了一些有關(guān)多線程的基本概念衣洁。本篇博文介紹的是iOS中常用的幾個多...
    nuclear閱讀 2,046評論 6 18
  • NSThread 第一種:通過NSThread的對象方法 NSThread *thread = [[NSThrea...
    攻城獅GG閱讀 789評論 0 3
  • #import "ViewController.h" @interface ViewController () @...
    艾克12138閱讀 252評論 0 0
  • 10.2 鐵廠 10.13老太太 10.14老太太 10.15老太太 10.16老太太
    盧火火313閱讀 223評論 0 0