iOS多線程以及在項(xiàng)目中的使用

  • pThread幾乎不用寝蹈,不用管
  • NSThread

NSThread是對(duì)pThread的封裝
優(yōu)點(diǎn):
1.實(shí)時(shí)性更高
2.與RunLoop結(jié)合,提供更為靈活高效的線程管理方式
缺點(diǎn):
1.創(chuàng)建線程代時(shí)班套,需要同時(shí)占用應(yīng)用和內(nèi)核的內(nèi)2.存空間(GCD只占用內(nèi)核的內(nèi)存空間)
編寫線程相關(guān)代碼相對(duì)繁雜

線程的創(chuàng)建方式

    [NSThread detachNewThreadWithBlock:^{
        NSLog(@"NSThread");
    }];
    // 2.
    [NSThread detachNewThreadSelector:@selector(dosomething:) toTarget:self withObject:data];
    // 3.
    NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(dosomething:) object:data];
    thread.name = @"thread1";
    [thread start];
  • GCD

項(xiàng)目中使用dispatch_async處理證件信息修改對(duì)OCR識(shí)別到大圖片壓縮耗時(shí)操作,壓縮完成后去請(qǐng)求接口蹦浦,JJ的做任務(wù)下載用了dispatch_group_t,還有JJ的檢測(cè)最優(yōu)線路也用了dispatch_group_t等

dispatch_sync同步
dispatch_async異步任務(wù)派發(fā)
dispatch_queue_t串行隊(duì)列與并發(fā)隊(duì)列
dispatch_once_t只執(zhí)行一次
dispatch_after延后執(zhí)行
dispatch_group_t組調(diào)度
dispatch_barrier_(a)sync柵欄
dispatch_semaphore信號(hào)量

dispatch_semaphore 是信號(hào)量模孩,但當(dāng)信號(hào)總量設(shè)為 1 時(shí)也可以當(dāng)作鎖來(lái)琳要。在沒有等待情況出現(xiàn)時(shí)衫嵌,它的性能比 pthread_mutex(自旋鎖) 還要高,但一旦有等待情況出現(xiàn)時(shí)砂心,性能就會(huì)下降許多懈词。相對(duì)于 OSSpinLock 來(lái)說,它的優(yōu)勢(shì)在于等待時(shí)不會(huì)消耗 CPU 資源辩诞。對(duì)磁盤緩存來(lái)說坎弯,它比較合適。自旋鎖更適合內(nèi)存緩存,雖然占用一些CPU荞怒,但是快

//可設(shè)置最大并發(fā)數(shù)洒琢,目前最大并發(fā)數(shù)為5,設(shè)置最大并發(fā)數(shù)還是建議用NSOperation
dispatch_semaphore_t sem = dispatch_semaphore_create(5);
//最大并發(fā)為1時(shí)也可以當(dāng)鎖使用
dispatch_semaphore_t sem = dispatch_semaphore_create(1);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
執(zhí)行耗時(shí)操作};
dispatch_async(dispatch_get_main_queue(), ^{
回到主線程進(jìn)行UI刷新操作
};

GCD中dispatch_queue大致可以分為三類
全局的并行的queue

主線程的串行的queue
自定義的queue
全局的queue和主線程的queue結(jié)合使用(上邊提到的)就是我們平常最常用的一種用法褐桌,在異步線程中執(zhí)行耗時(shí)操作衰抑,然后在UI線程執(zhí)行刷新操作。
全局的queue我們可以通過dispatch_get_global_queue(0, 0)直接獲取荧嵌,這里有兩個(gè)參數(shù)呛踊,第一個(gè)表示線程執(zhí)行的優(yōu)先級(jí)(第二個(gè)參數(shù)是預(yù)留參數(shù)暫時(shí)沒用)
第一個(gè)參數(shù)有以下幾個(gè)狀態(tài)
DISPATCH_QUEUE_PRIORITY_HIGH 2
-》DISPATCH_QUEUE_PRIORITY_DEFAULT 0
-》DISPATCH_QUEUE_PRIORITY_LOW (-2)
-》DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN,具體打印結(jié)果看下面內(nèi)容
下面我們?cè)O(shè)置第一個(gè)參數(shù)默認(rèn)值為0

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"start task 1");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"end task 1");
    });
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"start task 2");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"end task 2");
    });
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"start task 3");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"end task 3");
    });

輸出結(jié)果
2021-03-16 15:49:52.344146+0800 TestDemo[54759:1269344] start task 2
2021-03-16 15:49:52.344151+0800 TestDemo[54759:1269347] start task 3
2021-03-16 15:49:52.344146+0800 TestDemo[54759:1269346] start task 1

2021-03-16 15:49:55.348151+0800 TestDemo[54759:1269346] end task 1
2021-03-16 15:49:55.348151+0800 TestDemo[54759:1269347] end task 3
2021-03-16 15:49:55.348218+0800 TestDemo[54759:1269344] end task 2

下面設(shè)置優(yōu)先級(jí)

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        NSLog(@"start task 0");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"end task 0");
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        NSLog(@"start task 1");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"end task 1");
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSLog(@"start task 2");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"end task 2");
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"start task 3");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"end task 3");
    });
021-03-16 16:04:20.881211+0800 TestDemo[54815:1279607] start task 2
2021-03-16 16:04:20.881211+0800 TestDemo[54815:1279609] start task 3
2021-03-16 16:04:20.922642+0800 TestDemo[54815:1279608] start task 1
2021-03-16 16:04:21.037538+0800 TestDemo[54815:1279606] start task 0
2021-03-16 16:04:23.882068+0800 TestDemo[54815:1279609] end task 3
2021-03-16 16:04:23.882066+0800 TestDemo[54815:1279607] end task 2
2021-03-16 16:04:24.057318+0800 TestDemo[54815:1279608] end task 1
2021-03-16 16:04:24.133597+0800 TestDemo[54815:1279606] end task 0

串行隊(duì)列和并發(fā)隊(duì)列
dispatch_queue_create(const char *label, dispatch_queue_attr_t attr),這個(gè)方法同樣也有兩個(gè)參數(shù)啦撮,第一個(gè)參數(shù)是確定唯一queue的一個(gè)標(biāo)識(shí)谭网,第二個(gè)參數(shù)創(chuàng)建queue的類型
DISPATCH_QUEUE_SERIAL(串行)
DISPATCH_QUEUE_CONCURRENT(并發(fā))

dispatch_queue_t myQueue = dispatch_queue_create("testQueue", DISPATCH_QUEUE_SERIAL(串行)/DISPATCH_QUEUE_CONCURRENT(并發(fā)));
    dispatch_async(myQueue, ^{
        NSLog(@"start task 1");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"end task 1");
    });
    dispatch_async(myQueue, ^{
        NSLog(@"start task 2");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"end task 2");
    });
    dispatch_async(myQueue, ^{
        NSLog(@"start task 3");
        [NSThread sleepForTimeInterval:3];
        NSLog(@"end task 3");
    });

串行隊(duì)列輸出結(jié)果
2021-03-16 16:28:15.643198+0800 TestDemo[55024:1292810] start task 1
2021-03-16 16:28:18.643548+0800 TestDemo[55024:1292810] end task 1
2021-03-16 16:28:18.643854+0800 TestDemo[55024:1292810] start task 2
2021-03-16 16:28:21.648152+0800 TestDemo[55024:1292810] end task 2
2021-03-16 16:28:21.648631+0800 TestDemo[55024:1292810] start task 3
2021-03-16 16:28:24.653826+0800 TestDemo[55024:1292810] end task 3

并發(fā)隊(duì)列輸出結(jié)果
2021-03-16 16:33:54.921235+0800 TestDemo[55071:1297272] start task 2
2021-03-16 16:33:54.921235+0800 TestDemo[55071:1297270] start task 1
2021-03-16 16:33:54.921243+0800 TestDemo[55071:1297271] start task 3
2021-03-16 16:33:57.923428+0800 TestDemo[55071:1297272] end task 2
2021-03-16 16:33:57.923442+0800 TestDemo[55071:1297271] end task 3
2021-03-16 16:33:57.923442+0800 TestDemo[55071:1297270] end task 1

dipatch_group(調(diào)度組)的使用,項(xiàng)目使用JJ的多章節(jié)任務(wù)下載赃春,等所有任務(wù)下載成功后彈窗提示已完成愉择,還有就是檢測(cè)最優(yōu)線路后刷新UI
重點(diǎn):
dispatch_group_enter()(入組)
dispatch_group_leave()(出組)

- (void)test{
  dispatch_group_t group = dispatch_group_create();

    dispatch_group_enter(group);
    [self sendRequest1:^{
        dispatch_group_leave(group);
    }];

    dispatch_group_enter(group);
    [self sendRequest2:^{
        dispatch_group_leave(group);
    }];

    dispatch_group_notify(group, dispatch_queue_create(0, 0), ^{
        NSLog(@"task over");
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"refresh ui");
        });
    });
}
- (void)sendRequest1:(void(^)())block {
//異步請(qǐng)求,請(qǐng)求結(jié)果后block回調(diào)
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSLog(@"start task 1");
    [NSThread sleepForTimeInterval:3];
    NSLog(@"end task 1");
    dispatch_async(dispatch_get_main_queue(), ^{
        if (block) {
            block();
        }
    });
});
}
- (void)sendRequest2:(void(^)())block {
//異步請(qǐng)求织中,請(qǐng)求結(jié)果后block回調(diào)
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSLog(@"start task 2");
    [NSThread sleepForTimeInterval:3];
    NSLog(@"end task 2");
    dispatch_async(dispatch_get_main_queue(), ^{
        if (block) {
            block();
        }
    });
});
}
輸出結(jié)果
2021-03-16 16:53:52.788430+0800 TestDemo[55332:1314700] start task 2
2021-03-16 16:53:52.788430+0800 TestDemo[55332:1314695] start task 1
2021-03-16 16:53:55.789766+0800 TestDemo[55332:1314700] end task 2
2021-03-16 16:53:55.789766+0800 TestDemo[55332:1314695] end task 1
2021-03-16 16:53:55.790373+0800 TestDemo[55332:1314695] task over
2021-03-16 16:53:55.790798+0800 TestDemo[55332:1314538] refresh ui

dispatch_once_t一次執(zhí)行锥涕,常用來(lái)實(shí)現(xiàn)單例模式,這里以單例模式實(shí)現(xiàn)的模板代碼為例展示dispatch_once_t的用法狭吼,其中的實(shí)例化語(yǔ)句只會(huì)被執(zhí)行一次:

+ (instancetype *)sharedInstance {
    static dispatch_once_t once = 0;
    static id sharedInstance = nil;
    dispatch_once(&once, ^{
        // 只實(shí)例化一次
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
}

dispatch_barrier_(a)sync 柵欄函數(shù)
通過Dispatch_barrier_async添加的操作會(huì)暫時(shí)阻塞當(dāng)前隊(duì)列层坠,即等待前面的并發(fā)操作都完成后執(zhí)行該阻塞操作,待其完成后后面的并發(fā)操作才可繼續(xù)刁笙∑苹ǎ可以將其比喻為一座霸道的獨(dú)木橋,是并發(fā)隊(duì)列中的一個(gè)并發(fā)障礙點(diǎn)疲吸,臨時(shí)阻塞并獨(dú)占座每。
可見使用Dispatch_barrier_async可以實(shí)現(xiàn)類似dispatch_group_t組調(diào)度的效果,同時(shí)主要的作用是避免數(shù)據(jù)競(jìng)爭(zhēng),高效訪問數(shù)據(jù)磅氨。

??官方說明大意:在使用柵欄函數(shù)時(shí).使用自定義隊(duì)列才有意義,如果用的是串行隊(duì)列或者系統(tǒng)提供的全局并發(fā)隊(duì)列,這個(gè)柵欄函數(shù)的作用等同于一個(gè)同步函數(shù)的作用

☆??關(guān)于dispatch_barrier_(a)sync區(qū)別
個(gè)人理解:dispatch_barrier_sync 需要等待柵欄執(zhí)行完才會(huì)執(zhí)行柵欄后面的任務(wù),而dispatch_barrier_async 無(wú)需等待柵欄執(zhí)行完,會(huì)繼續(xù)往下走(保留在隊(duì)列里)

/* 創(chuàng)建并發(fā)隊(duì)列 */
    dispatch_queue_t concurrentQueue = dispatch_queue_create("test.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);
    /* 添加兩個(gè)并發(fā)操作A和B尺栖,即A和B會(huì)并發(fā)執(zhí)行 */
    dispatch_async(concurrentQueue, ^(){
        NSLog(@"OperationA");
    });
    dispatch_async(concurrentQueue, ^(){
        NSLog(@"OperationB");
    });
    /* 添加barrier障礙操作嫡纠,會(huì)等待前面的并發(fā)操作結(jié)束烦租,并暫時(shí)阻塞后面的并發(fā)操作直到其完成 */
    dispatch_barrier_async(concurrentQueue, ^(){
        NSLog(@"OperationBarrier!");
    });
    NSLog(@"驗(yàn)證async和sync的區(qū)別--現(xiàn)在是async");
    /* 繼續(xù)添加并發(fā)操作C和D,要等待barrier障礙操作結(jié)束才能開始 */
    dispatch_async(concurrentQueue, ^(){
        NSLog(@"OperationC");
    });
    dispatch_async(concurrentQueue, ^(){
        NSLog(@"OperationD");
    });
?? dispatch_barrier_async輸出結(jié)果
2021-03-16 17:33:09.429076+0800 TestDemo[55672:1343472] OperationB
2021-03-16 17:33:09.429084+0800 TestDemo[55672:1343332] 驗(yàn)證async和sync的區(qū)別--現(xiàn)在是async
2021-03-16 17:33:09.429090+0800 TestDemo[55672:1343476] OperationA
2021-03-16 17:33:09.429235+0800 TestDemo[55672:1343476] OperationBarrier!
2021-03-16 17:33:09.429327+0800 TestDemo[55672:1343476] OperationC
2021-03-16 17:33:09.429329+0800 TestDemo[55672:1343472] OperationD

??dispatch_barrier_sync輸出結(jié)果
2021-03-16 17:34:36.483220+0800 TestDemo[55690:1345240] OperationB
2021-03-16 17:34:36.483245+0800 TestDemo[55690:1345246] OperationA
2021-03-16 17:34:36.483487+0800 TestDemo[55690:1345114] OperationBarrier!
2021-03-16 17:34:36.483578+0800 TestDemo[55690:1345114] 驗(yàn)證async和sync的區(qū)別--現(xiàn)在是sync
2021-03-16 17:34:36.483675+0800 TestDemo[55690:1345242] OperationD
2021-03-16 17:34:36.483681+0800 TestDemo[55690:1345246] OperationC

dispatch_after
通過該函數(shù)可以讓要提交的任務(wù)在從提交開始后的指定時(shí)間后執(zhí)行除盏,也就是定時(shí)延遲執(zhí)行提交的任務(wù)叉橱,使用方法很簡(jiǎn)單:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            //延遲執(zhí)行
        });
  • NSOperation 和 NSOperationQueue

項(xiàng)目中的使用:例如微信分享圖片時(shí),等圖片下載完后再分享者蠕,用的NSOperationQueue
當(dāng) NSOperation 支持了 cancel 操作時(shí)窃祝,NSOperationQueue 可以使用 cancelAllOperatoins 來(lái)對(duì)所有的 operation 執(zhí)行 cancel 操作。
不過 cancel 的效果還是取決于 NSOperation 中代碼是怎么寫的踱侣。(比如 對(duì)于數(shù)據(jù)庫(kù)的某些操作線程來(lái)說粪小,cancel 可能會(huì)意味著 你需要把數(shù)據(jù)恢復(fù)到最原始的狀態(tài)大磺。)

maxConcurrentOperationCount設(shè)置最大并發(fā)數(shù)
默認(rèn)的最大并發(fā) operation 數(shù)量是由系統(tǒng)當(dāng)前的運(yùn)行情況決定的(來(lái)源),我們也可以強(qiáng)制指定一個(gè)固定的并發(fā)數(shù)量探膊。

GCD 與 NSOperation 的對(duì)比杠愧,面試中會(huì)經(jīng)常問,因?yàn)檫@兩個(gè)都很強(qiáng)大逞壁,我們也都經(jīng)常在用

  • NSOperationQueue 是基于 GCD 的更高層的封裝(從 OS X 10.10 開始可以通過設(shè)置 underlyingQueue 來(lái)把 operation 放到已有的 dispatch queue 中流济。)
  • 從易用性角度,GCD 由于采用 C 風(fēng)格的 API腌闯,在調(diào)用上比使用面向?qū)ο箫L(fēng)格的 NSOperation 要簡(jiǎn)單一些绳瘟。
  • 從對(duì)任務(wù)的控制性來(lái)說,NSOperation 顯著得好于 GCD姿骏,和 GCD 相比支持了 Cancel 操作(注:在 iOS8 中 GCD 引入了 dispatch_block_cancel 和 dispatch_block_testcancel糖声,也可以支持 Cancel 操作了),支持任務(wù)之間的依賴關(guān)系分瘦,支持同一個(gè)隊(duì)列中任務(wù)的優(yōu)先級(jí)設(shè)置姨丈,同時(shí)還可以通過 KVO 來(lái)監(jiān)控任務(wù)的執(zhí)行情況。(這些通過 GCD 也可以實(shí)現(xiàn)擅腰,不過需要很多代碼蟋恬,使用 NSOperation 顯得方便了很多。)
  • 從第三方庫(kù)的角度趁冈,知名的第三方庫(kù)如 AFNetworking 和 SDWebImage 背后都是使用 NSOperation歼争,也從另一方面說明對(duì)于需要復(fù)雜并發(fā)控制的需求,NSOperation 可能是更好的選擇渗勘,但也并不絕對(duì)沐绒,各有利弊,這只是個(gè)人理解旺坠。

NSOperation的使用
maxConcurrentOperationCount設(shè)置對(duì)大并發(fā)數(shù)
??切勿添加循環(huán)依賴

- (void)test
{
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"11111111%@", [NSThread currentThread]);
    }];
      
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"22222%@", [NSThread currentThread]);
    }];
      
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        sleep(3);
        NSLog(@"333333 %@", [NSThread currentThread]);
    }];
      
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"44444444%@", [NSThread currentThread]);
    }];
      
    // 指定操作之間的”依賴“關(guān)系乔遮,某一個(gè)操作的執(zhí)行,必須等待另一個(gè)操作完成才會(huì)開始
    // 依賴關(guān)系是可以跨隊(duì)列指定的
    [op2 addDependency:op1];
    [op3 addDependency:op2];
    [op4 addDependency:op3];
    // *** 添加依賴的時(shí)候取刃,注意不要出現(xiàn)循環(huán)依賴
//    [op3 addDependency:op4];
      
    [self.queue addOperation:op1];
    [self.queue addOperation:op2];
    [self.queue addOperation:op3];
    // 主隊(duì)列更新UI
    [[NSOperationQueue mainQueue] addOperation:op4];
}
- (NSOperationQueue *)queue
{
    if (!_queue) _queue = [[NSOperationQueue alloc] init];
    return _queue;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蹋肮,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子璧疗,更是在濱河造成了極大的恐慌坯辩,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件崩侠,死亡現(xiàn)場(chǎng)離奇詭異漆魔,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門改抡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)矢炼,“玉大人,你說我怎么就攤上這事阿纤÷闵荆” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵阵赠,是天一觀的道長(zhǎng)涯塔。 經(jīng)常有香客問我,道長(zhǎng)清蚀,這世上最難降的妖魔是什么匕荸? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮枷邪,結(jié)果婚禮上榛搔,老公的妹妹穿的比我還像新娘。我一直安慰自己东揣,他們只是感情好践惑,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嘶卧,像睡著了一般尔觉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上芥吟,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天侦铜,我揣著相機(jī)與錄音,去河邊找鬼钟鸵。 笑死钉稍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棺耍。 我是一名探鬼主播贡未,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蒙袍!你這毒婦竟也來(lái)了俊卤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤左敌,失蹤者是張志新(化名)和其女友劉穎瘾蛋,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矫限,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叼风。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片取董。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖无宿,靈堂內(nèi)的尸體忽然破棺而出茵汰,到底是詐尸還是另有隱情,我是刑警寧澤孽鸡,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布蹂午,位于F島的核電站,受9級(jí)特大地震影響彬碱,放射性物質(zhì)發(fā)生泄漏豆胸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一巷疼、第九天 我趴在偏房一處隱蔽的房頂上張望晚胡。 院中可真熱鬧,春花似錦嚼沿、人聲如沸估盘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)遣妥。三九已至,卻和暖如春攀细,著一層夾襖步出監(jiān)牢的瞬間燥透,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工辨图, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留班套,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓故河,卻偏偏與公主長(zhǎng)得像吱韭,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鱼的,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

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