iOS底層-25:GCD及使用

簡(jiǎn)介

GCD全稱Drand Central Dispatch

  • c語(yǔ)言,提供了非常多強(qiáng)大的函數(shù)

什么是GCD

將任務(wù)添加到隊(duì)列,并且指定執(zhí)行任務(wù)的函數(shù)

GCD的優(yōu)勢(shì):

  1. GCD是蘋果公司為多核的并行運(yùn)算提供的解決方案。
  2. GCD會(huì)自動(dòng)利用更多的CPU內(nèi)核(比如雙核员魏、四核)
  3. GCD會(huì)自動(dòng)管理線程周期(創(chuàng)建線程、調(diào)度任務(wù)叠聋、銷毀線程)
    程序員只需要告訴GCD想執(zhí)行什么任務(wù)撕阎,并不需要編寫任何線程管理代碼

基礎(chǔ)寫法

    //任務(wù)
    dispatch_block_t block = ^{
        NSLog(@"hello world");
    };
    //創(chuàng)建串行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.ly", NULL);
    //異步函數(shù)
    dispatch_async(queue, block);

這就是將任務(wù)添加到隊(duì)列,并通過(guò)異步函數(shù)執(zhí)行碌补。

  • 任務(wù)使用block封裝虏束,任務(wù)的block沒(méi)有參數(shù)也沒(méi)有返回值名斟。

  • 異步函數(shù) dispatch_async
    不用等待當(dāng)前語(yǔ)句執(zhí)行完畢,就可以執(zhí)行下一條語(yǔ)句

    • 會(huì)開啟線程執(zhí)行block任務(wù)魄眉,異步是多線程的代名詞
  • 同步函數(shù) dispatch_sync
    必須等到當(dāng)前語(yǔ)句執(zhí)行完畢砰盐,才可以執(zhí)行下一條語(yǔ)句

    • 不會(huì)開啟線程,在當(dāng)前線程中執(zhí)行block任務(wù)

同步和異步耗能問(wèn)題

同步函數(shù)

    CFAbsoluteTime time = CFAbsoluteTimeGetCurrent();
    //創(chuàng)建串行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.ly", NULL);

    //同步函數(shù)
    dispatch_sync(queue, ^{
   
    });
    
    NSLog(@"%f",CFAbsoluteTimeGetCurrent() - time);

打印結(jié)果:

 0.000008

異步函數(shù)

    CFAbsoluteTime time = CFAbsoluteTimeGetCurrent();
    //創(chuàng)建串行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.ly", NULL);

    //異步函數(shù)
    dispatch_async(queue, ^{
//        NSLog(@"任務(wù)1");
    });
    
    NSLog(@"%f",CFAbsoluteTimeGetCurrent() - time);
 0.000027

空任務(wù)時(shí)坑律,同步函數(shù)耗時(shí)更少岩梳。

添加一個(gè)NSLog任務(wù)

  • 同步函數(shù)
    CFAbsoluteTime time = CFAbsoluteTimeGetCurrent();
    //創(chuàng)建串行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.ly", NULL);

    //同步函數(shù)
    dispatch_sync(queue, ^{
        NSLog(@"任務(wù)1");
    });
    
    NSLog(@"%f",CFAbsoluteTimeGetCurrent() - time);

打印結(jié)果

 任務(wù)1
 0.000099
  • 異步函數(shù)
    CFAbsoluteTime time = CFAbsoluteTimeGetCurrent();
    //創(chuàng)建串行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.ly", NULL);

    //異步步函數(shù)
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)1");
    });
    
    NSLog(@"%f",CFAbsoluteTimeGetCurrent() - time);

打印結(jié)果:

 0.000025
  任務(wù)1

一個(gè)簡(jiǎn)簡(jiǎn)單單的打印語(yǔ)句,同步函數(shù)耗費(fèi)時(shí)間遠(yuǎn)大于異步函數(shù)晃择。

同步和異步函數(shù)都會(huì)耗費(fèi)時(shí)間冀值,異步函數(shù)多用來(lái)解決并發(fā)和多線程問(wèn)題。

隊(duì)列

串行隊(duì)列:按照任務(wù)指派的順序來(lái)執(zhí)行任務(wù)宫屠,前一個(gè)執(zhí)行完列疗,下一個(gè)才能執(zhí)行
并行隊(duì)列:能夠同時(shí)執(zhí)行一個(gè)或多個(gè)任務(wù)執(zhí)行任務(wù)的順序不一定

切勿將串行隊(duì)列浪蹂、并行對(duì)隊(duì)列和同步抵栈、異步混淆

函數(shù)與隊(duì)列搭配

函數(shù)與隊(duì)列搭配使用
同步函數(shù)與串行隊(duì)列
    //創(chuàng)建串行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.ly", NULL);
    //同步函數(shù)
    
    dispatch_sync(queue, ^{
        NSLog(@"任務(wù)1");
        sleep(2);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"任務(wù)2");
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"任務(wù)3");
    });

打印結(jié)果:

 任務(wù)1
 任務(wù)2
 任務(wù)3
同步函數(shù)與并行隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //同步函數(shù)
    
    dispatch_sync(queue, ^{
        NSLog(@"任務(wù)1");
        sleep(2);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"任務(wù)2");
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"任務(wù)3");
    });

打印結(jié)果

 任務(wù)1
 任務(wù)2
 任務(wù)3
異步函數(shù)與串行隊(duì)列
    //創(chuàng)建串行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.ly", NULL);
    //同步函數(shù)
    
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)1");
        sleep(2);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)2");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)3");
      
    });
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)4");
      
    });
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)5");
       
    });
異步函數(shù)與并行隊(duì)列
    //并行隊(duì)列 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //同步函數(shù)
    
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)1");
        sleep(2);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)2");
        sleep(2);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)3");
        sleep(2);
    });
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)4");
        sleep(2);
    });
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)5");
        sleep(2);
    });

打印結(jié)果

任務(wù)2
任務(wù)1
任務(wù)3
任務(wù)4
任務(wù)5

面試題

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    //創(chuàng)建串行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.ly", DISPATCH_QUEUE_CONCURRENT);

    NSLog(@"任務(wù)1");
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)2");
        dispatch_async(queue, ^{
            NSLog(@"任務(wù)3");
        });
        NSLog(@"任務(wù)4");
    });
    
    NSLog(@"任務(wù)5");   
}

異步函數(shù)和并發(fā)隊(duì)列不會(huì)阻塞線程。

打印結(jié)果:
任務(wù)1
任務(wù)5
任務(wù)2
任務(wù)4
任務(wù)3

  • 修改一個(gè)同步函數(shù)
    dispatch_queue_t queue = dispatch_queue_create("com.ly",   DISPATCH_QUEUE_CONCURRENT);

    NSLog(@"任務(wù)1");
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)2");
        dispatch_sync(queue, ^{
            NSLog(@"任務(wù)3");
        });
        NSLog(@"任務(wù)4");
    });
    
    NSLog(@"任務(wù)5");

打印結(jié)果為:

任務(wù)1
任務(wù)5
任務(wù)2
任務(wù)3
任務(wù)4
  • 將隊(duì)列改為串行隊(duì)列
     //創(chuàng)建串行隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.ly", NULL);

    NSLog(@"任務(wù)1");
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)2");
        dispatch_sync(queue, ^{
            NSLog(@"任務(wù)3");
        });
        NSLog(@"任務(wù)4");
    });
    
    NSLog(@"任務(wù)5");

打印結(jié)果:

任務(wù)1
任務(wù)5
任務(wù)2
崩潰

面試題2:

    dispatch_queue_t queue = dispatch_queue_create("com.ly", DISPATCH_QUEUE_CONCURRENT);

    
    dispatch_async(queue, ^{
        NSLog(@"1");
    });
    dispatch_async(queue, ^{
        NSLog(@"2");
    });
    dispatch_sync(queue, ^{
        NSLog(@"3");
    });
    NSLog(@"0");
    dispatch_sync(queue, ^{
        NSLog(@"7");
    });
    dispatch_sync(queue, ^{
        NSLog(@"8");
    });
    dispatch_sync(queue, ^{
        NSLog(@"9");
    });

答案為:AC
3必須在0之前坤次,0在789之前古劲,123無(wú)序 789 無(wú)序

    //A. 1230789
    //B. 1237890
    //C. 3120798
    //D. 2137890 

主隊(duì)列與全局隊(duì)列

主隊(duì)列:

  • 專門用來(lái)在主線程上調(diào)度任務(wù)的串行隊(duì)列
  • 不會(huì)開啟線程
  • 如果當(dāng)前主線程有任務(wù)正在執(zhí)行,那么無(wú)論主隊(duì)列中被添加了什么任務(wù)缰猴,都不會(huì)被調(diào)度
    -dispatch_get_main_queue()

全局隊(duì)列

  • 為了方便程序員的使用产艾,蘋果提供了全局隊(duì)列dispatch_get_global_queue(0, 0)
  • 全局隊(duì)列是一個(gè)并發(fā)隊(duì)列
  • 在使用多線程開發(fā)時(shí),如果對(duì)隊(duì)列沒(méi)有特殊要求滑绒,在執(zhí)行異步任務(wù)的時(shí)候闷堡,可以直接使用全局隊(duì)列

死鎖現(xiàn)象
主線程因?yàn)槟阃胶瘮?shù)的原因先執(zhí)行任務(wù),主隊(duì)列等待著主線程中的任務(wù)執(zhí)行完畢疑故,在執(zhí)行自己的任務(wù)杠览,主線程和主隊(duì)列相互等待會(huì)造成死鎖。

GCD用法

  1. 單例
static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"創(chuàng)建單例");
    });
  1. 同步/異步函數(shù)
//同步函數(shù)
 dispatch_sync(queue, ^{
        NSLog(@"3-%@",[NSThread currentThread]);
    });
//異步函數(shù)
 dispatch_async(queue, ^{
        NSLog(@"4-%@",[NSThread currentThread]);
    });
  1. dispatch_source
  • CPU負(fù)荷小焰扳,盡量不占用系統(tǒng)資源
  • 聯(lián)結(jié)的優(yōu)勢(shì)
    在任一線程上調(diào)用它的一個(gè)函數(shù)dispatch_source_merge_data后倦零,會(huì)執(zhí)行dispatch_source實(shí)現(xiàn)定義好的句柄(可以把句柄簡(jiǎn)單理解為一個(gè)block)误续,這個(gè)過(guò)程叫做Custom event吨悍,用戶事件。是dispatch_source支持的一種事件蹋嵌。

句柄是一種指向指針的指針育瓜,它指向的就是一個(gè)類或者結(jié)構(gòu),它和系統(tǒng)有很密切的關(guān)系栽烂。HINSTANCE(實(shí)例句柄)躏仇、HBITMAP(位圖句柄)恋脚、HDC(設(shè)備表述句柄)、HICON(圖標(biāo)句柄)等焰手。這其中還有一個(gè)通用句柄糟描,就是HANDLE

dispatch_source_create 創(chuàng)建源
dispatch_source_set_event_handler 設(shè)置源事件回調(diào)
dispatch_source_merge_data 源事件設(shè)置數(shù)據(jù)
dispatch_source_get_data 獲取源事件數(shù)據(jù)
dispatch_resume 繼續(xù) 
dispatch_suspend 掛起

簡(jiǎn)單例子

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.totalComplete = 0;
    
    self.queue = dispatch_queue_create("ly.com", NULL);
    // 不依賴 runloop
    // 和下層內(nèi)核 kenel-workloop交互
    // DISPATCH_SOURCE_TYPE_TIMER 準(zhǔn)確
    self.source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_get_main_queue());
    
    dispatch_source_set_event_handler(self.source, ^{
        
        NSLog(@"%@",[NSThread currentThread]);
        
        NSUInteger value = dispatch_source_get_data(self.source);
        self.totalComplete += value;
        NSLog(@"進(jìn)度: %.2f",self.totalComplete/100.0);
        self.progressView.progress = self.totalComplete/100.0;
    });
    
    self.isRunning = YES;
    dispatch_resume(self.source);
}



- (IBAction)didClickStartOrPauseAction:(id)sender {
   
    if (self.isRunning) {
        dispatch_suspend(self.source);
        dispatch_suspend(self.queue);
        NSLog(@"已經(jīng)暫停");
        self.isRunning = NO;
        [sender setTitle:@"暫停中.." forState:UIControlStateNormal];
    }else{
        dispatch_resume(self.source);
        dispatch_resume(self.queue);
        NSLog(@"已經(jīng)執(zhí)行了");
        self.isRunning = YES;
        [sender setTitle:@"執(zhí)行中.." forState:UIControlStateNormal];
    }
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    NSLog(@"開始了");
    
    for (int i= 0; i<100; i++) {
        dispatch_async(self.queue, ^{
            if (!self.isRunning) {
                NSLog(@"已經(jīng)暫停");
                return;
            }
            sleep(1);
            dispatch_source_merge_data(self.source, 1);
        });
    }
}
  1. 柵欄函數(shù)
    dispatch_async(queue, ^{
        NSLog(@"1");
        
    });
    dispatch_async(queue, ^{
        NSLog(@"2");
        NSLog(@"2-%@",[NSThread currentThread]);
    });
    
    dispatch_barrier_async(queue, ^{
        NSLog(@"3");
    });
    dispatch_async(queue, ^{
        NSLog(@"4");
    });

1、2執(zhí)行完才會(huì)執(zhí)行3书妻、4
柵欄函數(shù)船响,堵塞的是隊(duì)列

  • 保護(hù)數(shù)據(jù)寫入
    dispatch_queue_t concurrentQueue = dispatch_queue_create("cooci", DISPATCH_QUEUE_CONCURRENT);

    for (int i = 0; i<5000; i++) {
        dispatch_async(concurrentQueue, ^{
            NSString *imageName = [NSString stringWithFormat:@"%d.jpg", (i % 10)];
            NSURL *url = [[NSBundle mainBundle] URLForResource:imageName withExtension:nil];
            NSData *data = [NSData dataWithContentsOfURL:url];
            UIImage *image = [UIImage imageWithData:data];
            @synchronized (self) {
                [self.mArray addObject:image];
            }
        });
    }

多線程同時(shí)向數(shù)組中寫入數(shù)據(jù)時(shí),可能會(huì)出現(xiàn)問(wèn)題躲履,上面使用了同步鎖见间。也可以使用柵欄函數(shù)

    dispatch_queue_t concurrentQueue = dispatch_queue_create("cooci", DISPATCH_QUEUE_CONCURRENT);

    for (int i = 0; i<5000; i++) {
        dispatch_async(concurrentQueue, ^{
            NSString *imageName = [NSString stringWithFormat:@"%d.jpg", (i % 10)];
            NSURL *url = [[NSBundle mainBundle] URLForResource:imageName withExtension:nil];
            NSData *data = [NSData dataWithContentsOfURL:url];
            UIImage *image = [UIImage imageWithData:data];
            
            dispatch_barrier_async(concurrentQueue, ^{
                [self.mArray addObject:image];
            });
        });
    }
  • 柵欄函數(shù)不能使用全局隊(duì)列
    將上面代碼對(duì)列改為全局隊(duì)列,運(yùn)行會(huì)崩潰
    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(0, 0);
    
    for (int i = 0; i<5000; i++) {
        dispatch_async(concurrentQueue, ^{
            NSString *imageName = [NSString stringWithFormat:@"%d.jpg", (i % 10)];
            NSURL *url = [[NSBundle mainBundle] URLForResource:imageName withExtension:nil];
            NSData *data = [NSData dataWithContentsOfURL:url];
            UIImage *image = [UIImage imageWithData:data];
            
            dispatch_barrier_async(concurrentQueue, ^{
                [self.mArray addObject:image];
            });
        });
    }

崩潰效果圖:


原因:
柵欄函數(shù)主要是攔截隊(duì)列工猜,不讓隊(duì)列后面的任務(wù)執(zhí)行米诉。而系統(tǒng)的全局隊(duì)列,不只是添加了我們寫的任務(wù)篷帅,系統(tǒng)也會(huì)使用這個(gè)隊(duì)列史侣,添加任務(wù)被攔截才導(dǎo)致崩潰

  1. 調(diào)度組 dispatch_group_t
    __block int a, b;
    dispatch_queue_t queue = dispatch_queue_create("com.ly", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        a = 3;
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        b = 4;
        dispatch_group_leave(group);
    });

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"%d",a+b);
    });
  • 進(jìn)組和出組必須成對(duì)存在
  • 只有當(dāng)group中的任務(wù)都執(zhí)行完畢才會(huì)走dispatch_group_notify里的方法
  • dispatch_group_async相當(dāng)于dispatch_group_enter()dispatch_group_leave()
  1. 延遲
  2. 線程通訊
  3. 信號(hào)量/鎖
    信號(hào)量的簡(jiǎn)單使用:
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_semaphore_t sem = dispatch_semaphore_create(2);
    //任務(wù)1
    dispatch_async(queue, ^{
        dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
        NSLog(@"執(zhí)行任務(wù)1");
        sleep(1);
        NSLog(@"任務(wù)1完成");
        
    });
    
    //任務(wù)2
    dispatch_async(queue, ^{
        dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
        NSLog(@"執(zhí)行任務(wù)2");
        sleep(1);
        NSLog(@"任務(wù)2完成");
        dispatch_semaphore_signal(sem);
    });
    
    //任務(wù)3
    dispatch_async(queue, ^{
        dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
        NSLog(@"執(zhí)行任務(wù)3");
        sleep(1);
        NSLog(@"任務(wù)3完成");
        dispatch_semaphore_signal(sem);
    });

信號(hào)量創(chuàng)建的大小只有2魏身,所以1抵窒、2任務(wù)會(huì)一起執(zhí)行;執(zhí)行完畢之后才會(huì)執(zhí)行3叠骑。

GCD不像NSOperation可以直接控制并發(fā)數(shù)李皇,設(shè)置maxConcurrentOperationCount;它需要借助信號(hào)量來(lái)實(shí)現(xiàn)這一需求宙枷。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末掉房,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子慰丛,更是在濱河造成了極大的恐慌卓囚,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诅病,死亡現(xiàn)場(chǎng)離奇詭異哪亿,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)贤笆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門蝇棉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人芥永,你說(shuō)我怎么就攤上這事篡殷。” “怎么了埋涧?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵板辽,是天一觀的道長(zhǎng)奇瘦。 經(jīng)常有香客問(wèn)我,道長(zhǎng)劲弦,這世上最難降的妖魔是什么耳标? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮邑跪,結(jié)果婚禮上麻捻,老公的妹妹穿的比我還像新娘。我一直安慰自己呀袱,他們只是感情好贸毕,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著夜赵,像睡著了一般明棍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寇僧,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天摊腋,我揣著相機(jī)與錄音,去河邊找鬼嘁傀。 笑死兴蒸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的细办。 我是一名探鬼主播橙凳,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼笑撞!你這毒婦竟也來(lái)了岛啸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤茴肥,失蹤者是張志新(化名)和其女友劉穎坚踩,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓤狐,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瞬铸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了础锐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗓节。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖郁稍,靈堂內(nèi)的尸體忽然破棺而出赦政,到底是詐尸還是另有隱情胜宇,我是刑警寧澤耀怜,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布恢着,位于F島的核電站,受9級(jí)特大地震影響财破,放射性物質(zhì)發(fā)生泄漏掰派。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一左痢、第九天 我趴在偏房一處隱蔽的房頂上張望靡羡。 院中可真熱鬧,春花似錦俊性、人聲如沸略步。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)趟薄。三九已至,卻和暖如春典徊,著一層夾襖步出監(jiān)牢的瞬間杭煎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工卒落, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留羡铲,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓儡毕,卻偏偏與公主長(zhǎng)得像也切,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子腰湾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

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