多線程之—GCD

文藝求關(guān)注.png
  • OK吁津,既然講到多線程铆隘,那就一次性把全部多線程的內(nèi)容介紹完畢~

?? 簡介

  • <h6>什么是GCD</h6>

    • 全稱是Grand Central Dispatch磅叛,可譯為“牛逼的中樞調(diào)度器”
    • 純C語言睦疫,提供了非常多強(qiáng)大的函數(shù)
  • <h6>GCD的優(yōu)勢</h6>

    • GCD是蘋果公司為多核并發(fā)運(yùn)算提出的解決方案
    • GCD會自動(dòng)利用更多的CPU內(nèi)核(比如雙核道盏、四核)
    • GCD會自動(dòng)管理線程的生命周期(創(chuàng)建線程莹菱、調(diào)度任務(wù)移国、銷毀線程)
    • 程序猿只需要告訴GCD想要執(zhí)行什么任務(wù),不需要編寫任何線程管理代碼
  • <h6>任務(wù)和隊(duì)列</h6>

    • 任務(wù):執(zhí)行什么操作
    • 隊(duì)列:用來存放任務(wù)
  • <h6>GCD的使用就2個(gè)步驟</h6>

    • 定制任務(wù)
      • 確定想要做的事情
    • 任務(wù)添加到隊(duì)列
      • GCD會自動(dòng)將隊(duì)列中的任務(wù)取出道伟,放到對應(yīng)的線程中執(zhí)行
      • 任務(wù)的取出遵循隊(duì)列FIFO原則:先進(jìn)先出迹缀,后進(jìn)后出
  • <h6>執(zhí)行任務(wù)</h6>

    • GCD中有2個(gè)用來執(zhí)行任務(wù)的常用函數(shù)
  • <h6>異步函數(shù)</h6>

// 異步函數(shù) + 并發(fā)隊(duì)列: 開啟多條線程并發(fā)執(zhí)行隊(duì)列中的任務(wù)
// !!!*** 線程的數(shù)量并不是有任務(wù)的數(shù)量決定的使碾,而是由系統(tǒng)決定的
- (void)asyncConcurrent {
  • 1.1 獲得并發(fā)隊(duì)列-------------第一種方式
    /**
     第一個(gè)參數(shù) C語言字符串 隊(duì)列表的名稱(一般用公司域名:com.vn_vincent.www.DownloadQueue)
     第二個(gè)參數(shù) 隊(duì)列的類型
              DISPATCH_QUEUE_CONCURRENT:并發(fā)隊(duì)列
              DISPATCH_QUEUE_SERIAL:串行隊(duì)列
     */
    dispatch_queue_t queue = dispatch_queue_create("com.vn_vincent.www.DownLoadQueue", DISPATCH_QUEUE_CONCURRENT);
  • 1.2 獲得并發(fā)隊(duì)列-----------------第二種方式
    /**
     第一個(gè)參數(shù):隊(duì)列的優(yōu)先級,一般傳default/0
     第二個(gè)參數(shù):留給未來使用的祝懂,總是傳一個(gè)0 就可以了
     */
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  • 2.0 封裝任務(wù) 并把任務(wù)添加到隊(duì)列中
    dispatch_async(queue, ^{
        NSLog(@"downLoad1-------------%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"downLoad2-------------%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"downLoad3-------------%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"downLoad4-------------%@", [NSThread currentThread]);
    });
}
// 異步函數(shù) + 串行隊(duì)列: 開啟一條子線程票摇,串行執(zhí)行任務(wù)
- (void)asyncSerial {
  • 1.0 獲得并發(fā)隊(duì)列
    /**
     第一個(gè)參數(shù) C語言字符串 隊(duì)列表的名稱(一般用公司域名:com.vn_vincent.www.DownloadQueue)
     第二個(gè)參數(shù) 隊(duì)列的類型 description#>
              DISPATCH_QUEUE_CONCURRENT:并發(fā)隊(duì)列
              DISPATCH_QUEUE_SERIAL:串行隊(duì)列
     */
    dispatch_queue_t queue = dispatch_queue_create("com.vn_vincent.www.DownLoadQueue", DISPATCH_QUEUE_SERIAL);
  • 2.0 封裝任務(wù) 并把任務(wù)添加到隊(duì)列中
    dispatch_async(queue, ^{
        NSLog(@"downLoad1-------------%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"downLoad2-------------%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"downLoad3-------------%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"downLoad4-------------%@", [NSThread currentThread]);
    });
}
// 異步函數(shù) + 主隊(duì)列:不會開子線程,所有任務(wù)都在主線程中串行執(zhí)行
- (void)asyncMain {
  • 1.0 獲得主隊(duì)列
    dispatch_queue_t queue = dispatch_get_main_queue();
  • 2.0封裝任務(wù) 并把任務(wù)封裝到隊(duì)列中去

    dispatch_sync(queue, ^{
        NSLog(@"downLoad1-----------------%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"downLoad2-----------------%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"downLoad3-----------------%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"downLoad4-----------------%@", [NSThread currentThread]);
    });
}

<b>同步函數(shù):dispatch_sync

  • 不具備開子線程的能力砚蓬,可以開子線程
  • 執(zhí)行任務(wù)的方式:同步

異步函數(shù):dispatch_async

  • 具備開線程的能力
  • 執(zhí)行任務(wù)的方式:異步

隊(duì)列的類型

  • “并發(fā)隊(duì)列”:隊(duì)列中的任務(wù)可以同時(shí)執(zhí)行(異步)

    • 獲得方法:
      1?? 自己創(chuàng)建(concurrent)
      2?? 全局并發(fā)隊(duì)列
  • “串行隊(duì)列”:隊(duì)列中的任務(wù)只能一個(gè)接著一個(gè)的執(zhí)行

    • 獲得方法:
      1?? 自己創(chuàng)建(serial)
      2?? 主隊(duì)列:串行 | 在主隊(duì)列中的所有的任務(wù)都必須在主隊(duì)列中執(zhí)行 | 調(diào)度時(shí)比較特殊(矢门!)
      </b>
  • <b>同步函數(shù)</b>

// 同步函數(shù) + 并發(fā)隊(duì)列: 不會開子線程,所有任務(wù)在當(dāng)前線程中串行執(zhí)行
- (void)syncConcurrent {
  • 1.0 獲得并發(fā)隊(duì)列
    /**
     第一個(gè)參數(shù) C語言字符串 隊(duì)列表的名稱(一般用公司域名:com.vn_vincent.www.DownloadQueue)
     第二個(gè)參數(shù) 隊(duì)列的類型
     DISPATCH_QUEUE_CONCURRENT:并發(fā)隊(duì)列
     DISPATCH_QUEUE_SERIAL:串行隊(duì)列
     */
    dispatch_queue_t queue = dispatch_queue_create("com.vn_vincent.www.DownLoadQueue", DISPATCH_QUEUE_CONCURRENT);
  • 2.0 封裝任務(wù) 并把任務(wù)添加到隊(duì)列中去
    dispatch_sync(queue, ^{
        NSLog(@"downLoad1-------------%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"download2-------------%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"downLoad3-------------%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"download4-------------%@", [NSThread currentThread]);
    });
}
// 同步函數(shù) + 串行隊(duì)列: 不會開子線程灰蛙,所以任務(wù)在當(dāng)前線程中串行執(zhí)行
- (void)syncSerial {
  • 1.0 獲得并發(fā)隊(duì)列
    /**
     第一個(gè)參數(shù) C語言字符串 隊(duì)列表的名稱(一般用公司域名:com.vn_vincent.www.DownloadQueue)
     第二個(gè)參數(shù) 隊(duì)列的類型 description#>
     DISPATCH_QUEUE_CONCURRENT:并發(fā)隊(duì)列
     DISPATCH_QUEUE_SERIAL:串行隊(duì)列
     */
    dispatch_queue_t queue = dispatch_queue_create("com.vn_vincent.www.DownloadQueue", DISPATCH_QUEUE_SERIAL);
  • 2.0 封裝任務(wù) 并把任務(wù)添加到隊(duì)列中去

    dispatch_sync(queue, ^{
        NSLog(@"downLoad1-------------%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"downLoad2-------------%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"downLoad3-------------%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"downLoad4-------------%@", [NSThread currentThread]);
    });
}
// 同步函數(shù) + 主隊(duì)列:會發(fā)生死鎖
- (void)syncMain {
  • 1.0 獲取主隊(duì)列
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    NSLog(@"start");
    // **!! 當(dāng)主隊(duì)列中有任務(wù)要執(zhí)行的時(shí)候祟剔,會安排主線程來執(zhí)行任務(wù),\
            但是在安排之前會先檢查主線程的狀態(tài)摩梧,如果空閑則執(zhí)行物延,否則就暫停調(diào)度 \
            等待到主線程空閑為止
  • 2.0 封裝任務(wù) 并把任務(wù)封裝到隊(duì)列中去
    dispatch_sync(queue, ^{
        NSLog(@"downLoad1-----------------%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"downLoad2-----------------%@", [NSThread currentThread]);
    });
    
    dispatch_sync(queue, ^{
        NSLog(@"downLoad3-----------------%@", [NSThread currentThread]);
    });
}
  • <b>GCD線程間通信</b>
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
  • GCD開子線程— 1.0(并發(fā)|串行)獲得隊(duì)列
//    DISPATCH_QUEUE_PRIORITY_DEFAULT == 0
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
  • 2.0 封裝任務(wù),異步 | 完成線程間通信
    dispatch_async(queue, ^{
        NSURL *url = [NSURL URLWithString:@""];
        NSData *imageData = [NSData dataWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:imageData];
        
        // 回到主線程刷新UI
        // 下面方法也可以實(shí)現(xiàn)線程間通信
//        [self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>]
        
        // dispatch_get_main_queue()
        // 異步函數(shù)(同步函數(shù)) + 主隊(duì)列
        dispatch_async(dispatch_get_main_queue(), ^{
            self.imageView.image = image;
        });
    });
}
  • <b>GCD中常見的函數(shù)</b></br>
  • 一次性函數(shù) 1)整個(gè)程序運(yùn)行中只會執(zhí)行一次 2)線程安全
- (void)once {
    
    NSLog(@"start");
    static dispatch_once_t onceToken;
    // 內(nèi)部實(shí)現(xiàn)原理:最開始 onceToken == 0障本;如果onceToken == 0教届,那么就執(zhí)行一次下面的block代碼塊,onceToken == -1
    dispatch_once(&onceToken, ^{
        NSLog(@"once");
    });
}
  • GCD延遲操作
- (void)defer {
    
    NSLog(@"start");
  • 延遲的第一種方法:NSTimer
    [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(tesk) userInfo:nil repeats:NO];
  • 延遲的第二種方法:
    [self performSelector:@selector(tesk) withObject:nil afterDelay:2.0];
  • 延遲的第三種方法:GCD
    // * == 乘 GCD中事件事件單位為納秒(nm)
    /**
     主隊(duì)列:主線程
     全局并發(fā)隊(duì)列:子線程
     自己創(chuàng)建的并發(fā)隊(duì)列:子線程
     自己創(chuàng)建的穿行隊(duì)列:子線程
     dispatch_after:本質(zhì)上是一個(gè)異步函數(shù)
     */
//    dispatch_queue_t queue = dispatch_get_main_queue();
//    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//    dispatch_queue_t queue = dispatch_queue_create("com.vn_vincent.www", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t queue = dispatch_queue_create("com.vn_vincent.www", DISPATCH_QUEUE_SERIAL);
    // 內(nèi)部實(shí)現(xiàn)原理:延遲2秒驾霜,然后再把任務(wù)提交到隊(duì)列中
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"GCD---------%@", [NSThread currentThread]);
    });
}
- (void) tesk {
    NSLog(@"tesk");
}
  • GCD迭代
- (void)apply {

    // 迭代 == 遍歷
    // 特點(diǎn):在當(dāng)前線程中串行完成
    for (NSInteger i = 0; i < 10; i++) {
        NSLog(@"%zd-------------%@", i, [NSThread currentThread]);
    }
    
    NSLog(@"----------------------------------");
    /**
     GCD的快速迭代*(開發(fā)中一般使用并發(fā)隊(duì)列):會開啟子線程和主線程一起執(zhí)行任務(wù),所有的任務(wù)并發(fā)執(zhí)行
     第一個(gè)參數(shù) 遍歷次數(shù)
     第二個(gè)參數(shù) 隊(duì)列 ~ 線程
        傳入的隊(duì)列:自己創(chuàng)建的并發(fā)隊(duì)列 == 全局并發(fā)隊(duì)列
                  自己創(chuàng)建的串行隊(duì)列 == for in 循環(huán) (不會開啟子線程所有任務(wù)买置,串行執(zhí)行)
                  主隊(duì)列:產(chǎn)生死鎖
     第三個(gè)參數(shù) size_t 類似于for遍歷的中的 i
     */
    
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_apply(10, queue, ^(size_t i) {
        NSLog(@"%zd-------------%@", i, [NSThread currentThread]);
    });
}
  • GCD快速迭代應(yīng)用
- (void)moveImage {
    // 需求粪糙,桌面上有兩個(gè)文件夾(oldImage|newImage),要求忿项,將其中一個(gè)文件夾(oldImage)內(nèi)的所有文件剪切到另一個(gè)文件夾(newImage)中
    // 01.得到上級文件夾的路徑
    NSString *oldPath = @"/Users/Vincent/Desktop/oldImage";
    NSString *newPath = @"/Users/Vincent/Desktop/newImage";
    // 02.獲得所有文件
    NSArray *subPaths = [[NSFileManager defaultManager] subpathsAtPath:oldPath];
    NSLog(@"%@", subPaths);
    // 03.便利并剪切文件
    dispatch_apply(subPaths.count, dispatch_get_global_queue(0, 0), ^(size_t index) {
        
        NSString *fileName = subPaths[index];
        // 拼接字符串得到文件名
        NSString *oldFullPath = [oldPath stringByAppendingPathComponent:fileName];
        NSString *newFullPath = [newPath stringByAppendingPathComponent:fileName];
        // 04.剪切文件
        [[NSFileManager defaultManager] moveItemAtPath:oldFullPath toPath:newFullPath error:nil];
        
        NSLog(@"%@-------%@----------%@", oldFullPath, newFullPath, [NSThread currentThread]);
    });
}
  • GCD柵欄函數(shù)使用
// 柵欄函數(shù)不能使用全局并發(fā)隊(duì)列
- (void) barrier {

    // 需求:1)有四個(gè)任務(wù)蓉冈,開子線程并發(fā)的執(zhí)行這四個(gè)任務(wù)
    //      2) 添加任務(wù)“臨時(shí)任務(wù)”,但是要求必須要等1|2任務(wù)完成后執(zhí)行轩触,必須要等臨時(shí)任務(wù)完成寞酿,才能執(zhí)行后面的任務(wù)
    //      3)所有的任務(wù)都在子線程中完成(dispatch_async);
    //      4)"臨時(shí)任務(wù)“需要在子線程中完成(dispatch_sync);
  • 01.獲得并發(fā)隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.vn_vincent.www.TextQueue", DISPATCH_QUEUE_CONCURRENT);
  • 02.異步函數(shù)
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)1完成--------------%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)2完成--------------%@", [NSThread currentThread]);
    });
    // 柵欄函數(shù)  Barrier
    dispatch_barrier_async(queue, ^{
        NSLog(@"+++++++臨時(shí)任務(wù)+++++++++, %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)3完成--------------%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)4完成--------------%@", [NSThread currentThread]);
    });
}
  • GCD 隊(duì)列組
- (void)groupQueue01 {
  • 01.創(chuàng)建隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
  • 02.創(chuàng)建隊(duì)列組
    dispatch_group_t group = dispatch_group_create();
  • 03.封裝任務(wù),并把任務(wù)添加到異步隊(duì)列
    /**
     1) 封裝任務(wù)
     2) 把任務(wù)添加到隊(duì)列中
    dispatch_async(queue, ^{
        NSLog(@"%@", [NSThread currentThread]);
    });
     */
    
    /**
     1) 封裝任務(wù)
     2) 把任務(wù)添加到隊(duì)列中
     3)會監(jiān)聽任務(wù)的執(zhí)行情況脱柱,通知group
     */
    dispatch_group_async(group, queue, ^{
        NSLog(@"1------------------%@", [NSThread currentThread]);
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"2------------------%@", [NSThread currentThread]);
    });
    
    dispatch_group_async(group, queue, ^{
        NSLog(@"3------------------%@", [NSThread currentThread]);
    });
    // 攔截通知伐弹,當(dāng)隊(duì)列中所有任務(wù)的任務(wù)都執(zhí)行完畢的時(shí)候會進(jìn)行下面的任務(wù)執(zhí)行
    // 內(nèi)部本身是異步的,不會堵塞
    dispatch_group_notify(group, queue, ^{
        NSLog(@"----------------dispatch_group_notify------------------");
    });
    // 攔截通知的另一種方法
    // DISPATCH_TIME_FOREVER 等待榨为,死等.直到隊(duì)列中所有的任務(wù)都執(zhí)行完畢之后才會執(zhí)行
    // 阻塞的
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    NSLog(@"------------end-------------");
}
  • 老寫法
- (void)groupQueue02 {
  • 01.創(chuàng)建隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
  • 02.創(chuàng)建隊(duì)列組
    dispatch_group_t group = dispatch_group_create();
  • 03.在該方法后面的異步任務(wù)會被納入到隊(duì)列組的監(jiān)聽范圍惨好,進(jìn)入群組
  • dispatch_group_enter | dispatch_group_leave 必須要配對使用
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"1--------------%@", [NSThread currentThread]);
        
        // 離開群組
        dispatch_group_leave(group);
    });
    
    dispatch_async(queue, ^{
        NSLog(@"2--------------%@", [NSThread currentThread]);
        
        // 離開群組
        dispatch_group_leave(group);
    });
    dispatch_group_notify(group, queue, ^{
        NSLog(@"-----------------dispatch_group_notify-------------------");
    });
}
  • GCD 隊(duì)列組使用(需求,下載兩個(gè)圖片随闺,并將兩個(gè)圖片合并成一張圖片)
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

// 第一張圖
@property (nonatomic, strong) UIImage *image1;
// 第二張圖
@property (nonatomic, strong) UIImage *image2;
- (void) groupQueueAdhibition {
  • 01.創(chuàng)建隊(duì)列組
    dispatch_group_t group = dispatch_group_create();
  • 02.獲取并發(fā)隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
  • 03.下載圖片一日川,開子線程
    dispatch_group_async(group, queue, ^{
        
        // 3.1.獲取圖片的URL
        NSURL *url = [NSURL URLWithString:@"http://scimg.jb51.net/allimg/151109/14-15110Z9535JH.jpg"];
        
        // 3.2.下載圖片的二進(jìn)制數(shù)據(jù)
        NSData *image1Data = [NSData dataWithContentsOfURL:url];
        
        // 3.3.轉(zhuǎn)換圖片
        self.image1 = [UIImage imageWithData:image1Data];
    });
  • 04.下載圖片二,開子線程
    dispatch_group_async(group, queue, ^{
        
        // 4.1.獲取圖片的URL
        NSURL *url = [NSURL URLWithString:@"http://pic.qiantucdn.com/58pic/18/12/74/50B58PICWPb_1024.jpg"];
        
        // 4.2.下載圖片的二進(jìn)制數(shù)據(jù)
        NSData *image2Data = [NSData dataWithContentsOfURL:url];
        
        // 4.3.轉(zhuǎn)換圖片
        self.image2 = [UIImage imageWithData:image2Data];
    });
  • 05.合并圖片
    dispatch_group_notify(group, queue, ^{
        // 5.1 創(chuàng)建圖形上下文
        UIGraphicsBeginImageContext(CGSizeMake(300, 300));
        
        // 5.2 畫圖1
        [self.image1 drawInRect:CGRectMake(0, 0, 300, 150)];
        self.image1 = nil;
        
        // 5.3 畫圖2
        [self.image2 drawInRect:CGRectMake(0, 150, 300, 150)];
        self.image2 = nil;
        
        // 5.4 根據(jù)上下文得到一張圖片
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        
        // 5.5 關(guān)閉上下文
        UIGraphicsEndImageContext();
        
        // 5.6 刷新UI
       dispatch_async(dispatch_get_main_queue(), ^{
           self.imageView.image = image;
       });
        
    });
}
  • GCD補(bǔ)充知識點(diǎn)
- (void) test02 {
    
//    dispatch_async(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    // 封裝任務(wù)的方法不同(??:Block矩乐, ??:函數(shù))
    /**
     第一個(gè)參數(shù):隊(duì)列
     第二個(gè)參數(shù):函數(shù)參數(shù)
     第三個(gè)參數(shù):要調(diào)用的函數(shù)名稱
     */
    // 會開子線程龄句,完成任務(wù)
    dispatch_async_f(dispatch_get_global_queue(0, 0), NULL, task);
    dispatch_async_f(dispatch_get_global_queue(0, 0), NULL, task);
    dispatch_async_f(dispatch_get_global_queue(0, 0), NULL, task);
}

void task(void *param) {

    NSLog(@"%s-----------%@", __func__, [NSThread currentThread]);
}
關(guān)注一下又不會懷孕.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子分歇,更是在濱河造成了極大的恐慌透葛,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卿樱,死亡現(xiàn)場離奇詭異僚害,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)繁调,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進(jìn)店門萨蚕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蹄胰,你說我怎么就攤上這事岳遥。” “怎么了裕寨?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵浩蓉,是天一觀的道長。 經(jīng)常有香客問我宾袜,道長捻艳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任庆猫,我火速辦了婚禮认轨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘月培。我一直安慰自己嘁字,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布杉畜。 她就那樣靜靜地躺著纪蜒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪此叠。 梳的紋絲不亂的頭發(fā)上纯续,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機(jī)與錄音拌蜘,去河邊找鬼杆烁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛简卧,可吹牛的內(nèi)容都是我干的兔魂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼举娩,長吁一口氣:“原來是場噩夢啊……” “哼析校!你這毒婦竟也來了构罗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤智玻,失蹤者是張志新(化名)和其女友劉穎遂唧,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吊奢,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡盖彭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了页滚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片召边。...
    茶點(diǎn)故事閱讀 39,711評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖裹驰,靈堂內(nèi)的尸體忽然破棺而出隧熙,到底是詐尸還是另有隱情,我是刑警寧澤幻林,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布贞盯,位于F島的核電站,受9級特大地震影響沪饺,放射性物質(zhì)發(fā)生泄漏躏敢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一随闽、第九天 我趴在偏房一處隱蔽的房頂上張望父丰。 院中可真熱鬧,春花似錦掘宪、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至坟漱,卻和暖如春鼠次,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芋齿。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工腥寇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人觅捆。 一個(gè)月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓赦役,卻偏偏與公主長得像,于是被迫代替她去往敵國和親栅炒。 傳聞我的和親對象是個(gè)殘疾皇子掂摔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評論 2 353

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