iOS開發(fā)中多線程的使用

互斥鎖/線程同步(@synchronized(對(duì)象))

  • 用途:為了解決一塊資源被多個(gè)線程共享造成的數(shù)據(jù)紊亂數(shù)據(jù)安全問題
  • 只要被@synchronized的{}包裹起來的代碼荔棉,同一時(shí)刻就只能被一個(gè)線程執(zhí)行
  • 注意:
  1. 只要加鎖就會(huì)消耗性能
  2. 加鎖必須傳遞一個(gè)對(duì)象,作為鎖(一般都是傳self)
  3. 如果想真正的鎖住代碼,那么多個(gè)線程必須使用同一把鎖才行
  4. 加鎖的時(shí)候盡量縮小范圍堵泽,因?yàn)榉秶酱笮阅芫驮降?/li>

多線程的實(shí)現(xiàn)方案

1.Pthread(C):基本不用
2.NSThread(OC):可拿到線程對(duì)象桐绒,設(shè)置線程的一些屬性降淮,結(jié)束線程等
3.GCD(C):用的最多乞旦,使用最簡(jiǎn)單(不能拿到線程续膳,開始了就很難手動(dòng)結(jié)束)
4.NSOperation(OC):抽象類,要使用其子類

Pthread

// 第一個(gè)參數(shù): 線程的代號(hào)(當(dāng)做就是線程)
// 第二個(gè)參數(shù): 線程的屬性
// 第三個(gè)參數(shù): 指向函數(shù)的指針, 就是將來線程需要執(zhí)行的方法
// 第四個(gè)參數(shù): 給第三個(gè)參數(shù)的指向函數(shù)的指針 傳遞的參數(shù)
pthread_t threadId;
// 只要create一次就會(huì)創(chuàng)建一個(gè)新的線程
pthread_create(&threadId , NULL, &demo, "lnj");

NSThread

  • 注意:如果正在執(zhí)行系統(tǒng)分離出來的線程(子線程)時(shí)胖替,系統(tǒng)內(nèi)部會(huì)retain當(dāng)前線程研儒,只有線程中的方法執(zhí)行完畢,系統(tǒng)才會(huì)將其釋放(release)

  • 創(chuàng)建方式一(可拿到子線程對(duì)象設(shè)置一些屬性独令,需要手動(dòng)開啟子線程)

    // 創(chuàng)建子線程
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    
    // 設(shè)置線程的其他屬性
    thread.name = @"second";
    
    // 開啟子線程
    [thread start];
  • 創(chuàng)建方式二(不能拿到子線程對(duì)象端朵,不需要手動(dòng)開啟子線程,快速
    // 創(chuàng)建子線程
    [NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
    ```

- 創(chuàng)建方式三(系統(tǒng)自動(dòng)創(chuàng)建子線程并在self的@selector方法中執(zhí)行燃箭,**快速**)
    ```objc
    // 第三種創(chuàng)建方式
    [self performSelectorInBackground:@selector(run) withObject:nil];
  • 常用方法
+ (NSThread *)mainThread; // 獲得主線程
- (BOOL)isMainThread; // 是否為主線程
+ (BOOL)isMainThread; // 是否為主線程

// 獲取當(dāng)前線程(最常用)
[NSThread currentThread]; 

// 線程的調(diào)度優(yōu)先級(jí)冲呢,調(diào)度優(yōu)先級(jí)的取值范圍是0.0 ~ 1.0,默認(rèn)0.5遍膜,值越大碗硬,優(yōu)先級(jí)越高
+ (double)threadPriority;
+ (BOOL)setThreadPriority:(double)p;
- (double)threadPriority;
- (BOOL)setThreadPriority:(double)p;

// 線程的名字
- (void)setName:(NSString *)n;
- (NSString *)name;

// 阻塞(暫停)線程,**如果想實(shí)現(xiàn)延長啟動(dòng)圖片的顯示時(shí)間可在application的didFinish方法中用此方法讓線程睡一會(huì)**
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;

// 強(qiáng)制停止線程
+ (void)exit;

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ù)、銷毀線程)
    4.程序員只需要告訴GCD想要執(zhí)行什么任務(wù)挽懦,不需要編寫任何線程管理代碼

  • GCD中有2個(gè)核心概念

    • 任務(wù):執(zhí)行什么操作
    • 隊(duì)列:用來存放任務(wù)
  • GCD的使用就2步
    1.定制任務(wù)(確定要執(zhí)行什么)
    2.將任務(wù)添加到隊(duì)列(GCD會(huì)自動(dòng)將隊(duì)列中的任務(wù)取出翰意,放到對(duì)應(yīng)的線程中執(zhí)行,任務(wù)的取出遵循隊(duì)列的FIFO原則:先進(jìn)先出信柿,后進(jìn)后出)

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

    • 同步:只能在當(dāng)前線程中執(zhí)行任務(wù)冀偶,不具備開啟新線程的能力
// queue:隊(duì)列
// block:任務(wù)
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);   
  • 異步:可以在新的線程中執(zhí)行任務(wù),具備開啟新線程的能力
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
  • 隊(duì)列類型
    • 串行:讓任務(wù)一個(gè)接著一個(gè)地執(zhí)行(一個(gè)任務(wù)執(zhí)行完畢后渔嚷,再執(zhí)行下一個(gè)任務(wù))
// 串行隊(duì)列的創(chuàng)建
dispatch_queue_t queue = dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
    // 兩個(gè)參數(shù)分別是:隊(duì)列的名稱,隊(duì)列的類型
    // 創(chuàng)建串行隊(duì)列(隊(duì)列類型傳遞NULL或者DISPATCH_QUEUE_SERIAL)
  • 并發(fā):可以讓多個(gè)任務(wù)并發(fā)(同時(shí))執(zhí)行(自動(dòng)開啟多個(gè)線程同時(shí)執(zhí)行任務(wù))并發(fā)功能只有在異步(dispatch_async)函數(shù)下才有效
// 并發(fā)隊(duì)列的創(chuàng)建进鸠,兩個(gè)參數(shù)分別是:隊(duì)列的名稱,隊(duì)列的類型
dispatch_queue_t queue = dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
- 獲取全局并發(fā)隊(duì)列
// GCD默認(rèn)已經(jīng)提供了全局的并發(fā)隊(duì)列,供整個(gè)應(yīng)用使用形病,可以無需手動(dòng)創(chuàng)建
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    // 第一個(gè)參數(shù)是優(yōu)先級(jí)客年,傳0即可霞幅,第二參數(shù)暫時(shí)無用,傳0
- 全局并發(fā)隊(duì)列的優(yōu)先級(jí)
#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高
    #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默認(rèn)(中)
    #define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低
    #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后臺(tái)
- 獲取主隊(duì)列(**放在主隊(duì)列中的任務(wù)量瓜,都會(huì)放到主線程中執(zhí)行**)
// 主隊(duì)列是GCD自帶的一種特殊的串行隊(duì)列
dispatch_queue_t queue = dispatch_get_main_queue();
- *注意:使用sync函數(shù)往當(dāng)前串行隊(duì)列中添加任務(wù)司恳,會(huì)卡住當(dāng)前的串行隊(duì)列*
  • 任務(wù)函數(shù)和隊(duì)列類型的搭配使用
/*
 同步 + 主隊(duì)列 = 需要記住的就一點(diǎn): 同步函數(shù)不能搭配主隊(duì)列使用
 注意: 如果是在子線程中調(diào)用同步函數(shù) + 主對(duì)列 是可以執(zhí)行的
 */
- (void)syncMian
{
    // 主隊(duì)列, 只要將任務(wù)放到主隊(duì)列中, 那么任務(wù)就會(huì)在主線程中執(zhí)行
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    // 需要記住的就一點(diǎn): 同步函數(shù)不能搭配主隊(duì)列使用
    dispatch_sync(queue, ^{
        NSLog(@"1 - %@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2 - %@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3 - %@", [NSThread currentThread]);
    });
    
    NSLog(@"++++++++++++++");
}

/*
 異步 + 主隊(duì)列 = 不會(huì)開啟新的線程
 */
- (void)asyncMain
{
    // 主隊(duì)列, 只要將任務(wù)放到主隊(duì)列中, 那么任務(wù)就會(huì)在主線程中執(zhí)行
    dispatch_queue_t queue = dispatch_get_main_queue();
    // 如果任務(wù)放在主隊(duì)列中, 哪怕是異步方法也不會(huì)創(chuàng)建新的線程
    dispatch_async(queue, ^{
        NSLog(@"1 - %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2 - %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3 - %@", [NSThread currentThread]);
    });
}

/*
 同步 + 串行 = 不會(huì)創(chuàng)建新的線程
 注意: 如果是同步函數(shù), 只要代碼執(zhí)行到了同步函數(shù)的那一行, 就會(huì)立即執(zhí)行任務(wù), 只有任務(wù)執(zhí)行完畢才會(huì)繼續(xù)往后執(zhí)行
 */
- (void)syncSerial
{
    // 1.創(chuàng)建隊(duì)列
    /*
     正是因?yàn)榫€程默認(rèn)就是串行, 所以創(chuàng)建串行隊(duì)列的時(shí)候, 隊(duì)列類型可以不傳值
     */
    //    dispatch_queue_t queue = dispatch_queue_create("com.520it.lnj", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queue = dispatch_queue_create("com.520it.lnj", NULL);
    
    // 2.添加任務(wù)
    dispatch_sync(queue, ^{
        NSLog(@"1 - %@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2 - %@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3 - %@", [NSThread currentThread]);
    });
    
    NSLog(@"%s", __func__);
}

/*
 同步 + 并行 = 不會(huì)開啟新的線程
 注意: 能不能開啟新的線程, 和并行/串行沒有關(guān)系, 只要函數(shù)是同步還是異步
 */
- (void)syncConcurrent
{
    // 1.創(chuàng)建隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    // 2.添加任務(wù)
    dispatch_sync(queue, ^{
        NSLog(@"1 - %@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2 - %@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3 - %@", [NSThread currentThread]);
    });
    NSLog(@"%s", __func__);
}
/*
 異步 + 串行 = 會(huì)創(chuàng)建新的線程, 但是只會(huì)創(chuàng)建一個(gè)新的線程, 所有的任務(wù)都在這一個(gè)新的線程中執(zhí)行
 異步任務(wù), 會(huì)先執(zhí)行完所有的代碼, 再在子線程中執(zhí)行任務(wù)
 */
- (void)asyncSerial
{
    // 1.創(chuàng)建隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.520it.lnj", DISPATCH_QUEUE_SERIAL);
    
    // 2.添加任務(wù)
    dispatch_async(queue, ^{
        NSLog(@"1 - %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2 - %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3 - %@", [NSThread currentThread]);
    });
    NSLog(@"%s", __func__);
}

/*
 異步 +  并行 = 會(huì)開啟新的線程
 */
- (void)asynConcurrent
{
    /*
     第一個(gè)參數(shù): 隊(duì)列
     第二個(gè)參數(shù): 任務(wù)
     */
    // 1.創(chuàng)建隊(duì)列
    /*
     第一個(gè)參數(shù): 隊(duì)列的名稱
     第二個(gè)參數(shù): 隊(duì)列的類型
     */
    //    dispatch_queue_t queue = dispatch_queue_create("com.520it.lnj", DISPATCH_QUEUE_CONCURRENT);
    
    // 其實(shí)系統(tǒng)內(nèi)部已經(jīng)給我們提供了一個(gè)現(xiàn)成的并發(fā)隊(duì)列
    /*
     第一個(gè)參數(shù): iOS8以前是線程的優(yōu)先級(jí)/ iOS8以后代表服務(wù)質(zhì)量
     iOS8以前
     *  - DISPATCH_QUEUE_PRIORITY_HIGH: 2
     *  - DISPATCH_QUEUE_PRIORITY_DEFAULT: 0
     *  - DISPATCH_QUEUE_PRIORITY_LOW: -2
     *  - DISPATCH_QUEUE_PRIORITY_BACKGROUND: -32768
     
     iOS8開始, 取值都是十六進(jìn)制
     *  - QOS_CLASS_USER_INTERACTIVE 用戶交互(用戶迫切的想執(zhí)行任務(wù), 不要在這種服務(wù)質(zhì)量下做耗時(shí)的操作)
     *  - QOS_CLASS_USER_INITIATED   用戶需要
     *  - QOS_CLASS_DEFAULT          默認(rèn)(重置隊(duì)列)
     *  - QOS_CLASS_UTILITY          實(shí)用工具(耗時(shí)的操作放在這里)
     *  - QOS_CLASS_BACKGROUND
     *  - QOS_CLASS_UNSPECIFIED      沒有設(shè)置任何優(yōu)先級(jí)
     第二個(gè)參數(shù): 系統(tǒng)保留的參數(shù), 永遠(yuǎn)傳0
     */
    // 1.獲取全局的并發(fā)隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(0 , 0);
    
    // 2.添加任務(wù)到隊(duì)列
    // 文檔說明是FIFO原則, 先進(jìn)先出
    // 打印結(jié)果不正確的原因: 線程的執(zhí)行速度可能不一樣, 有得快一些, 有的慢一些
    dispatch_async(queue, ^{
        NSLog(@"1 - %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2 - %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3 - %@", [NSThread currentThread]);
    });
    NSLog(@"%s", __func__);
}
  • GCD的更多函數(shù)使用(延遲執(zhí)行delay,只執(zhí)行一次once绍傲,快速迭代apply扔傅,柵欄barrier,隊(duì)列組group)請(qǐng)移步GCD更多函數(shù)使用

NSOperation

  • 簡(jiǎn)介

    • NSOperation是個(gè)抽象類烫饼,并不具備封裝操作的能力猎塞,必須使用它的子類
    • 使用NSOperation子類的方式有3種
      • NSInvocationOperation
      • NSBlockOperation
      • 自定義子類繼承NSOperation,實(shí)現(xiàn)內(nèi)部相應(yīng)的方法
  • 配合使用NSOperation和NSOperationQueue也能實(shí)現(xiàn)多線程編程
    1.先將需要執(zhí)行的操作封裝到一個(gè)NSOperation對(duì)象中
    2.然后將NSOperation對(duì)象添加到NSOperationQueue中
    3.系統(tǒng)會(huì)自動(dòng)將NSOperationQueue中的NSOperation取出來
    4.將取出的NSOperation封裝的操作放到一條新線程中執(zhí)行

  • NSOperation使用注意

  • 用NSOperation的子類創(chuàng)建的任務(wù)如果沒有加入隊(duì)列中杠纵,需要手動(dòng)調(diào)用start方法邢享,且默認(rèn)不會(huì)增加新線程是在主線程中執(zhí)行,加入隊(duì)列中系統(tǒng)會(huì)自動(dòng)執(zhí)行

  • 用NSBlockOperation創(chuàng)建任務(wù)后調(diào)用addExecutionBlock:追加的任務(wù)默認(rèn)是在子線程中執(zhí)行

  • 如果用NSOperationQueue創(chuàng)建了隊(duì)列淡诗,且任務(wù)加入了隊(duì)列中,就不需要調(diào)用start方法伊履,系統(tǒng)會(huì)自動(dòng)從queue中取出任務(wù)在子線程中執(zhí)行

  • NSOperationQueue創(chuàng)建隊(duì)列后的快速添加任務(wù)方法

    // 此方法系統(tǒng)內(nèi)部會(huì)自動(dòng)封裝成一個(gè)NSBlockOperation然后再添加到隊(duì)列中
    [queue addOperationWithBlock:^{
        NSLog(@"4---%@",[NSThread currentThread]);
    }];
    
  • NSOperation的自定義任務(wù)韩容,繼承自NSOperation,實(shí)現(xiàn)main方法唐瀑,在main方法中輸入需要執(zhí)行的任務(wù)群凶,將自定義的任務(wù)加入隊(duì)列后,系統(tǒng)會(huì)自動(dòng)在子線程中執(zhí)行任務(wù)哄辣。

#import "SFWOperation.h" // SFWOperation是自定義的繼承自NSOperation的類
@implementation SFWOperation

// 只要將任務(wù)添加到了隊(duì)列中请梢,系統(tǒng)會(huì)自動(dòng)執(zhí)行自定義任務(wù)中的main方法
- (void)main{
 
    // 在這里寫上需要執(zhí)行的任務(wù)
    NSLog(@"%@",[NSThread currentThread]);
    for (int i = 0; i< 10000; i++) {
        NSLog(@"%d",i);
    }
}
@end
  • 參數(shù)的使用

  • maxConcurrentOperationCount最大并發(fā)數(shù)

    • 自己創(chuàng)建的隊(duì)列默認(rèn)是并發(fā),如果設(shè)置maxConcurrentOperationCount = 1,就是串行
    • 注意: 不能設(shè)置為0, 如果設(shè)置為0就不執(zhí)行任務(wù)
    • 默認(rèn)情況下maxConcurrentOperationCount = -1
    • 在開發(fā)中并發(fā)數(shù)最多盡量不要超過5~6條
  • suspended暫停任務(wù)

    • 只要設(shè)置隊(duì)列的suspended為YES,那么就會(huì)暫停隊(duì)列中其它任務(wù)的執(zhí)行
    • 也就是說不會(huì)再繼續(xù)執(zhí)行沒有執(zhí)行到的任務(wù)
    • 只要設(shè)置隊(duì)列的suspended為NO, 那么就會(huì)恢復(fù)隊(duì)列中其它任務(wù)的執(zhí)行
    • 注意:
      • 設(shè)置為暫停之后, 不會(huì)立即暫停
      • 會(huì)繼續(xù)執(zhí)行當(dāng)前正在執(zhí)行的任務(wù), 直到當(dāng)前任務(wù)執(zhí)行完畢, 就不會(huì)執(zhí)行下一個(gè)任務(wù)了
      • 也就是說, 暫停其實(shí)是暫停下一個(gè)任務(wù), 而不能暫停當(dāng)前任務(wù)
      • 暫停是可以恢復(fù)的
  • cancelAllOperations取消任務(wù)方法

    • 取消隊(duì)列中所有的任務(wù)的執(zhí)行
    • 取消和暫停一樣, 是取消后面的任務(wù), 不能取消當(dāng)前正在執(zhí)行的任務(wù)
    • 注意: 取消是不可以恢復(fù)的
  • addDependency:依賴方法

    // op3 依賴 op1,只有等op1的操作做完了以后才會(huì)開始o(jì)p3的操作
    [op3 addDependency:op1];
    
  • completionBlock:監(jiān)聽方法

    - (void (^)(void))completionBlock;
    - (void)setCompletionBlock:(void (^)(void))block;
    

線程間通信

  • 1個(gè)線程傳遞數(shù)據(jù)給另1個(gè)線程
  • 在1個(gè)線程中執(zhí)行完特定任務(wù)后力穗,轉(zhuǎn)到另1個(gè)線程繼續(xù)執(zhí)行任務(wù)
  • 常用方法:
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;

- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
    // waitUntilDone的含義: 
    如果傳入的是YES: 那么會(huì)等到主線程中的方法執(zhí)行完畢, 才會(huì)繼續(xù)執(zhí)行下面其他行的代碼
    如果傳入的是NO: 那么不用等到主線程中的方法執(zhí)行完畢, 就可以繼續(xù)執(zhí)行下面其他行的代碼
  • 從子線程回到主線程(加入主隊(duì)列)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 執(zhí)行耗時(shí)的異步操作...
      dispatch_async(dispatch_get_main_queue(), ^{
        // 回到主線程毅弧,執(zhí)行UI刷新操作
        });
});
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    // 創(chuàng)建隊(duì)列,獲取全局并行隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    
    // 添加下載任務(wù)到子線程中
    dispatch_async(queue, ^{
        
        NSLog(@"%@",[NSThread currentThread]);
        // 下載圖片
        NSURL *url = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/1b4c510fd9f9d72aee889e1fd22a2834359bbbc0.jpg"];
        NSData *data = [NSData dataWithContentsOfURL:url];
        
        UIImage *image = [UIImage imageWithData:data];
        
        // 顯示UI控件当窗,將此任務(wù)加入到主隊(duì)列中
        
        // 如果是通過異步函數(shù)添加任務(wù)够坐,會(huì)先執(zhí)行完所有代碼再來執(zhí)行block中的任務(wù)
        // 如果是通過同步函數(shù)添加的任務(wù),會(huì)先執(zhí)行完block中的任務(wù)再執(zhí)行其他代碼
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"%@",[NSThread currentThread]);
            self.imageView.image = image;
        });
        
    });
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末崖面,一起剝皮案震驚了整個(gè)濱河市元咙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌巫员,老刑警劉巖庶香,帶你破解...
    沈念sama閱讀 212,222評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異简识,居然都是意外死亡赶掖,警方通過查閱死者的電腦和手機(jī)感猛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來倘零,“玉大人唱遭,你說我怎么就攤上這事〕适唬” “怎么了拷泽?”我有些...
    開封第一講書人閱讀 157,720評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長袖瞻。 經(jīng)常有香客問我司致,道長,這世上最難降的妖魔是什么聋迎? 我笑而不...
    開封第一講書人閱讀 56,568評(píng)論 1 284
  • 正文 為了忘掉前任脂矫,我火速辦了婚禮,結(jié)果婚禮上霉晕,老公的妹妹穿的比我還像新娘庭再。我一直安慰自己,他們只是感情好牺堰,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,696評(píng)論 6 386
  • 文/花漫 我一把揭開白布拄轻。 她就那樣靜靜地躺著,像睡著了一般伟葫。 火紅的嫁衣襯著肌膚如雪恨搓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,879評(píng)論 1 290
  • 那天筏养,我揣著相機(jī)與錄音斧抱,去河邊找鬼。 笑死渐溶,一個(gè)胖子當(dāng)著我的面吹牛辉浦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掌猛,決...
    沈念sama閱讀 39,028評(píng)論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼盏浙,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了荔茬?” 一聲冷哼從身側(cè)響起废膘,我...
    開封第一講書人閱讀 37,773評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎慕蔚,沒想到半個(gè)月后丐黄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,220評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡孔飒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,550評(píng)論 2 327
  • 正文 我和宋清朗相戀三年灌闺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了艰争。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,697評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出诱建,到底是詐尸還是另有隱情论熙,我是刑警寧澤盯荤,帶...
    沈念sama閱讀 34,360評(píng)論 4 332
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏机错。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,002評(píng)論 3 315
  • 文/蒙蒙 一父腕、第九天 我趴在偏房一處隱蔽的房頂上張望弱匪。 院中可真熱鬧,春花似錦璧亮、人聲如沸萧诫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽财搁。三九已至,卻和暖如春躬络,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背搭儒。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評(píng)論 1 266
  • 我被黑心中介騙來泰國打工穷当, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人淹禾。 一個(gè)月前我還...
    沈念sama閱讀 46,433評(píng)論 2 360
  • 正文 我出身青樓馁菜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親铃岔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子汪疮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,587評(píng)論 2 350

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