iOS多線程

整理下幾種常用的處理多線程的類缀棍,并將該類對(duì)應(yīng)的常用方法整理下,采用簡(jiǎn)單直觀的例子展示匪凉。

1捌肴、NSThread

NSThread的創(chuàng)建方法有三種:

  • init方法蹬叭,需要start啟動(dòng)
  • detachNewThreadSelector方法,自動(dòng)啟動(dòng)
  • performSelectorInBackground方法状知,自動(dòng)啟動(dòng)

init方法

NSThread *threadInit = [[NSThread alloc] initWithTarget:self selector:@selector(thread_initMethod:) object:@"initMethod"];
[threadInit start];
- (void)thread_initMethod:(NSObject *)object
{
    NSLog(@"init方法 --> object:%@, %@",object, [NSThread currentThread]);
}

輸出結(jié)果:

init方法 --> object:initMethod, <NSThread: 0x60000027b180>{number = 3, name = (null)}

是在子線程中完成秽五。

detachNewThreadSelector方法

[NSThread detachNewThreadSelector:@selector(thread_detch:) toTarget:self withObject:@"detachNewThread"];
- (void)thread_detch:(NSObject *)object
{
    NSLog(@"detach方法 --> object:%@, %@",object, [NSThread currentThread]);
}

輸出結(jié)果:

detach方法 --> object:detachNewThread, <NSThread: 0x60000027b0c0>{number = 4, name = (null)}

是在子線程中完成。

performSelectorInBackground方法

[self performSelectorInBackground:@selector(thread_perform:) withObject:@"performSelectorInBackground"];
- (void)thread_perform:(NSObject *)object
{
    NSLog(@"perform方法--> object:%@, %@",object, [NSThread currentThread]);
}

輸出結(jié)果:

perform方法--> object:performSelectorInBackground, <NSThread: 0x60000007a2c0>{number = 5, name = (null)}

是在子線程中完成饥悴。

2坦喘、GCD

GCD中的基本概念:

  • 任務(wù):執(zhí)行的代碼塊
  • 隊(duì)列:存放任務(wù)的地方
  • 同步/異步:執(zhí)行的方式

GCD中的三種隊(duì)列類型:

  • The main queue:與主線程功能相同盲再。實(shí)際上,提交至main queue(主隊(duì)列)的任務(wù)會(huì)在主線程中執(zhí)行瓣铣。main queue可以調(diào)用dispatch_get_main_queue()來獲得答朋。因?yàn)閙ain queue是與主線程相關(guān)的,所以這是一個(gè)串行隊(duì)列棠笑。
  • Global queues:全局隊(duì)列是并發(fā)隊(duì)列梦碗,并由整個(gè)進(jìn)程共享。進(jìn)程中存在四個(gè)全局隊(duì)列:高腐晾、中(默認(rèn))叉弦、低丐一、后臺(tái)四個(gè)優(yōu)先級(jí)隊(duì)列藻糖。可以調(diào)用dispatch_get_global_queue函數(shù)傳入優(yōu)先級(jí)來訪問隊(duì)列库车。
  • 其他隊(duì)列: 其他隊(duì)列是用函數(shù)dispatch_queue_create創(chuàng)建的隊(duì)列巨柒。創(chuàng)建隊(duì)列,第一個(gè)參數(shù)是表示debug用的柠衍,Apple建議我們使用倒置域名來命名隊(duì)列洋满;第二個(gè)參數(shù)表示隊(duì)列類型:串行(DISPATCH_QUEUE_SERIAL)或者并發(fā)(DISPATCH_QUEUE_CONCURRENT)。

串行同步

dispatch_queue_t serialQueue = dispatch_queue_create("com.multithreading.serialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(serialQueue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"串行同步:%i --> %@",i, [NSThread currentThread]);
    }
});
dispatch_sync(serialQueue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"串行同步:%i --> %@",i, [NSThread currentThread]);
    }
});
dispatch_sync(serialQueue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"串行同步:%i --> %@",i, [NSThread currentThread]);
    }
});

輸出結(jié)果:

串行同步:0 --> <NSThread: 0x600000072d40>{number = 1, name = main}
串行同步:1 --> <NSThread: 0x600000072d40>{number = 1, name = main}
串行同步:2 --> <NSThread: 0x600000072d40>{number = 1, name = main}
串行同步:0 --> <NSThread: 0x60400007ee80>{number = 1, name = main}
串行同步:1 --> <NSThread: 0x60400007ee80>{number = 1, name = main}
串行同步:2 --> <NSThread: 0x60400007ee80>{number = 1, name = main}
串行同步:0 --> <NSThread: 0x60400007ee80>{number = 1, name = main}
串行同步:1 --> <NSThread: 0x60400007ee80>{number = 1, name = main}
串行同步:2 --> <NSThread: 0x60400007ee80>{number = 1, name = main}

都是在主線程中完成珍坊,沒有開辟新線程牺勾。

串行異步

dispatch_queue_t serialQueue = dispatch_queue_create("com.multithreading.serialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"串行異步:%i --> %@",i, [NSThread currentThread]);
    }
});
dispatch_async(serialQueue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"串行異步:%i --> %@",i, [NSThread currentThread]);
    }
});
dispatch_async(serialQueue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"串行異步:%i --> %@",i, [NSThread currentThread]);
    }
});

輸出結(jié)果:

串行異步:0 --> <NSThread: 0x604000467900>{number = 3, name = (null)}
串行異步:1 --> <NSThread: 0x604000467900>{number = 3, name = (null)}
串行異步:2 --> <NSThread: 0x604000467900>{number = 3, name = (null)}
串行異步:0 --> <NSThread: 0x604000467900>{number = 3, name = (null)}
串行異步:1 --> <NSThread: 0x604000467900>{number = 3, name = (null)}
串行異步:2 --> <NSThread: 0x604000467900>{number = 3, name = (null)}
串行異步:0 --> <NSThread: 0x604000467900>{number = 3, name = (null)}
串行異步:1 --> <NSThread: 0x604000467900>{number = 3, name = (null)}
串行異步:2 --> <NSThread: 0x604000467900>{number = 3, name = (null)}

開辟了一個(gè)新線程。

并發(fā)同步

dispatch_queue_t concurrentQueue = dispatch_queue_create("com.multithreading.concurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(concurrentQueue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"并發(fā)同步:%i --> %@",i, [NSThread currentThread]);
    }
});
dispatch_sync(concurrentQueue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"并發(fā)同步:%i --> %@",i, [NSThread currentThread]);
    }
});
dispatch_sync(concurrentQueue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"并發(fā)同步:%i --> %@",i, [NSThread currentThread]);
    }
});

輸出結(jié)果:

并發(fā)同步:0 --> <NSThread: 0x60000007c980>{number = 1, name = main}
并發(fā)同步:1 --> <NSThread: 0x60000007c980>{number = 1, name = main}
并發(fā)同步:2 --> <NSThread: 0x60000007c980>{number = 1, name = main}
并發(fā)同步:0 --> <NSThread: 0x60000007c980>{number = 1, name = main}
并發(fā)同步:1 --> <NSThread: 0x60000007c980>{number = 1, name = main}
并發(fā)同步:2 --> <NSThread: 0x60000007c980>{number = 1, name = main}
并發(fā)同步:0 --> <NSThread: 0x60000007c980>{number = 1, name = main}
并發(fā)同步:1 --> <NSThread: 0x60000007c980>{number = 1, name = main}
并發(fā)同步:2 --> <NSThread: 0x60000007c980>{number = 1, name = main}

在主線程中完成阵漏,沒有開辟新線程驻民。

并發(fā)異步

dispatch_queue_t concurrentQueue = dispatch_queue_create("com.multithreading.concurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentQueue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"并發(fā)異步:%i --> %@",i, [NSThread currentThread]);
    }
});
dispatch_async(concurrentQueue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"并發(fā)異步:%i --> %@",i, [NSThread currentThread]);
    }
});
dispatch_async(concurrentQueue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"并發(fā)異步:%i --> %@",i, [NSThread currentThread]);
    }
});

輸出結(jié)果:

并發(fā)異步:0 --> <NSThread: 0x600000277480>{number = 4, name = (null)}
并發(fā)異步:0 --> <NSThread: 0x604000465f80>{number = 3, name = (null)}
并發(fā)異步:0 --> <NSThread: 0x604000466140>{number = 5, name = (null)}
并發(fā)異步:1 --> <NSThread: 0x600000277480>{number = 4, name = (null)}
并發(fā)異步:1 --> <NSThread: 0x604000465f80>{number = 3, name = (null)}
并發(fā)異步:1 --> <NSThread: 0x604000466140>{number = 5, name = (null)}
并發(fā)異步:2 --> <NSThread: 0x600000277480>{number = 4, name = (null)}
并發(fā)異步:2 --> <NSThread: 0x604000465f80>{number = 3, name = (null)}
并發(fā)異步:2 --> <NSThread: 0x604000466140>{number = 5, name = (null)}

本例子中開了三條新線程。

主線程同步

- (void)mainQueueSync
{
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"任務(wù)1:%@",[NSThread currentThread]);
    });
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"任務(wù)2:%@",[NSThread currentThread]);
    });
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"任務(wù)3:%@",[NSThread currentThread]);
    });
}

輸出結(jié)果:

主線程鎖死履怯,崩潰

原因:主隊(duì)列同步會(huì)先執(zhí)行任務(wù)1回还,當(dāng)前主線程正在執(zhí)行mainQueueSync方法,造成執(zhí)行任務(wù)1等待mainQueueSync方法結(jié)束叹洲,mainQueueSync方法等待任務(wù)1~3任務(wù)結(jié)束柠硕。

線程通訊

dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSLog(@"做一些費(fèi)時(shí)的東西");
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"主線程刷新UI");
    });
});

輸出結(jié)果:

做一些費(fèi)時(shí)的東西
主線程刷新UI

柵欄

dispatch_queue_t queue = dispatch_queue_create("com.multithreading.fence", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"任務(wù)1:%i --> %@",i, [NSThread currentThread]);
    }
});
dispatch_async(queue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"任務(wù)2:%i --> %@",i, [NSThread currentThread]);
    }
});
dispatch_barrier_async(queue, ^{
    NSLog(@"------并發(fā)異步執(zhí)行柵欄分割------");
});
dispatch_async(queue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"任務(wù)3:%i --> %@",i, [NSThread currentThread]);
    }
});
dispatch_async(queue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"任務(wù)4:%i --> %@",i, [NSThread currentThread]);
    }
});

輸出結(jié)果:

任務(wù)2:0 --> <NSThread: 0x604000069940>{number = 4, name = (null)}
任務(wù)1:0 --> <NSThread: 0x60000026b780>{number = 3, name = (null)}
任務(wù)2:1 --> <NSThread: 0x604000069940>{number = 4, name = (null)}
任務(wù)1:1 --> <NSThread: 0x60000026b780>{number = 3, name = (null)}
任務(wù)2:2 --> <NSThread: 0x604000069940>{number = 4, name = (null)}
任務(wù)1:2 --> <NSThread: 0x60000026b780>{number = 3, name = (null)}
------并發(fā)異步執(zhí)行柵欄分割------
任務(wù)4:0 --> <NSThread: 0x604000069940>{number = 4, name = (null)}
任務(wù)3:0 --> <NSThread: 0x60000026b780>{number = 3, name = (null)}
任務(wù)4:1 --> <NSThread: 0x604000069940>{number = 4, name = (null)}
任務(wù)3:1 --> <NSThread: 0x60000026b780>{number = 3, name = (null)}
任務(wù)4:2 --> <NSThread: 0x604000069940>{number = 4, name = (null)}
任務(wù)3:2 --> <NSThread: 0x60000026b780>{number = 3, name = (null)}

異步是沒有順序的,但是添加了柵欄运提,可以將任務(wù)分為兩部分蝗柔,先做第一部分完畢后,才會(huì)做第二部分民泵。

隊(duì)列組

dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("com.multithreading.group", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_async(group, queue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"任務(wù)1:%i --> %@",i,[NSThread currentThread]);
    }
});
dispatch_group_async(group, queue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"任務(wù)2:%i --> %@",i,[NSThread currentThread]);
    }
});
dispatch_group_async(group, queue, ^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"任務(wù)3:%i --> %@",i,[NSThread currentThread]);
    }
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    NSLog(@"任務(wù)完了癣丧,回到主線程刷新UI");
});

輸出結(jié)果:

任務(wù)1:0 --> <NSThread: 0x60400027a080>{number = 3, name = (null)}
任務(wù)3:0 --> <NSThread: 0x604000279fc0>{number = 5, name = (null)}
任務(wù)2:0 --> <NSThread: 0x60400027a0c0>{number = 4, name = (null)}
任務(wù)1:1 --> <NSThread: 0x60400027a080>{number = 3, name = (null)}
任務(wù)2:1 --> <NSThread: 0x60400027a0c0>{number = 4, name = (null)}
任務(wù)3:1 --> <NSThread: 0x604000279fc0>{number = 5, name = (null)}
任務(wù)1:2 --> <NSThread: 0x60400027a080>{number = 3, name = (null)}
任務(wù)2:2 --> <NSThread: 0x60400027a0c0>{number = 4, name = (null)}
任務(wù)3:2 --> <NSThread: 0x604000279fc0>{number = 5, name = (null)}
任務(wù)完了,回到主線程刷新UI

開辟了三條線程洪灯,在任務(wù)1坎缭,2竟痰,3完成后會(huì),回調(diào)dispatch_group_notify方法掏呼,回到主線程刷新UI坏快。

3、NSOperation

NSOperation的創(chuàng)建:

  • 使用NSInvocationOperation子類憎夷,需要start開啟
  • 使用NSBlockOperation子類莽鸿,需要start開啟
  • 使用繼承NSOperation的子類,需要start開啟

NSInvocationOperation

NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationOperation:) object:@"invocation"];
[invocationOperation start];
- (void)invocationOperation:(NSObject *)object
{
    NSLog(@"invocation方法:%@",[NSThread currentThread]);
}

輸出結(jié)果:

invocation方法:<NSThread: 0x600000071ec0>{number = 1, name = main}

沒有開新線程拾给。

NSBlockOperation

NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"block方法:%@",[NSThread currentThread]);
}];
[blockOperation addExecutionBlock:^{
    NSLog(@"任務(wù)1:%@",[NSThread currentThread]);
}];
[blockOperation addExecutionBlock:^{
    NSLog(@"任務(wù)2:%@",[NSThread currentThread]);
}];
[blockOperation addExecutionBlock:^{
    NSLog(@"任務(wù)3:%@",[NSThread currentThread]);
}];
[blockOperation start];

輸出結(jié)果:

block方法:<NSThread: 0x7feaf1701590>{number = 1, name = main}
任務(wù)1:<NSThread: 0x7f839bc21280>{number = 2, name = (null)}
任務(wù)2:<NSThread: 0x7f839be44180>{number = 3, name = (null)}
任務(wù)3:<NSThread: 0x7f839be1f470>{number = 4, name = (null)}

blockOperationWithBlock方法:主線程實(shí)現(xiàn)祥得,不加入隊(duì)列就不會(huì)開辟新線程
addExecutionBlock方法:會(huì)開新線程

繼承NSOperation的子類

此例子中繼承NSOperation的子類名為DZROperation ,在.m文件中重寫main函數(shù)來實(shí)現(xiàn)任務(wù)

// DZROperation.h
#import <Foundation/Foundation.h>

@interface DZROperation : NSOperation

@end


// DZROperation.m
#import "DZROperation.h"

@implementation DZROperation

- (void)main
{
    for (int i = 0; i < 3; i++) {
        NSLog(@"DZROperation --> %i, %@",i, [NSThread currentThread]);
    }
}

@end
DZROperation *operation = [[DZROperation alloc] init];
[operation start];

輸出結(jié)果:

DZROperation --> 0, <NSThread: 0x7fd22ee01ae0>{number = 1, name = main}
DZROperation --> 1, <NSThread: 0x7fd22ee01ae0>{number = 1, name = main}
DZROperation --> 2, <NSThread: 0x7fd22ee01ae0>{number = 1, name = main}

沒有加入隊(duì)列蒋得,是在主線程中實(shí)現(xiàn)级及,未開辟新線程。

NSOperationQueue

NSOperationQueue隊(duì)列類型:

  • 主隊(duì)列
  • 非主隊(duì)列(串行额衙,并發(fā))

隊(duì)列NSOperationQueue有個(gè)參數(shù)最大并發(fā)數(shù):maxConcurrentOperationCount

  • maxConcurrentOperationCount默認(rèn)-1饮焦,直接開啟并發(fā),所以非主隊(duì)列默認(rèn)是開啟并發(fā)
  • maxConcurrentOperationCount > 1窍侧,進(jìn)行并發(fā)
  • maxConcurrentOperationCount = 1县踢,表示不開線程,是串行
  • maxConcurrentOperationCount系統(tǒng)會(huì)限制一個(gè)最大值伟件,所以設(shè)maxConcurrentOperationCount很大也是無意義的
添加自定義NSOperation類到隊(duì)列中
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
DZROperation *operation1 = [[DZROperation alloc] init];
DZROperation *operation2 = [[DZROperation alloc] init];
[queue addOperation:operation1];
[queue addOperation:operation2];

輸出結(jié)果:

DZROperation --> 0, <NSThread: 0x7fc46660c030>{number = 2, name = (null)}
DZROperation --> 0, <NSThread: 0x7fc466605c70>{number = 3, name = (null)}
DZROperation --> 1, <NSThread: 0x7fc46660c030>{number = 2, name = (null)}
DZROperation --> 1, <NSThread: 0x7fc466605c70>{number = 3, name = (null)}
DZROperation --> 2, <NSThread: 0x7fc46660c030>{number = 2, name = (null)}
DZROperation --> 2, <NSThread: 0x7fc466605c70>{number = 3, name = (null)}

此處的NSOperationQueue是默認(rèn)并發(fā)隊(duì)列硼啤,這里開了2個(gè)新線程

直接添加任務(wù)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
[queue addOperationWithBlock:^{
    NSLog(@"添加任務(wù)1:%@",[NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
    NSLog(@"添加任務(wù)2:%@",[NSThread currentThread]);
}];
[queue addOperationWithBlock:^{
    NSLog(@"添加任務(wù)3:%@",[NSThread currentThread]);
}];

輸出結(jié)果:

maxConcurrentOperationCount = -1輸出:
添加任務(wù)2:<NSThread: 0x7fa3a2f169f0>{number = 3, name = (null)}
添加任務(wù)1:<NSThread: 0x7fa3a2d09240>{number = 2, name = (null)}
添加任務(wù)3:<NSThread: 0x7fa3a2d0a3d0>{number = 4, name = (null)}

maxConcurrentOperationCount = 1輸出:
添加任務(wù)1:<NSThread: 0x7fe65270b6a0>{number = 2, name = (null)}
添加任務(wù)2:<NSThread: 0x7fe65270b6a0>{number = 2, name = (null)}
添加任務(wù)3:<NSThread: 0x7fe65270b6a0>{number = 2, name = (null)}

直接在block中實(shí)現(xiàn)任務(wù)。

operationQueue間通訊
// 主隊(duì)列
NSOperationQueue *mainOperation = [NSOperationQueue mainQueue];
// 并發(fā)隊(duì)列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
    NSLog(@"做復(fù)雜操作");
    
    [mainOperation addOperationWithBlock:^{
        NSLog(@"刷新UI");
    }];
}];

輸出結(jié)果:

做復(fù)雜操作
刷新UI

任務(wù)的執(zhí)行先后設(shè)定 -- 類似GCD的柵欄
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"任務(wù)1:%d, %@",i, [NSThread currentThread]);
    }
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
    for (int i = 0; i < 3; i++) {
        NSLog(@"任務(wù)2:%d, %@",i, [NSThread currentThread]);
    }
}];

// 任務(wù)1依賴任務(wù)2
[operation1 addDependency:operation2];
[queue addOperation:operation1];
[queue addOperation:operation2];

輸出結(jié)果:

任務(wù)2:0, <NSThread: 0x7fc82160c390>{number = 2, name = (null)}
任務(wù)2:1, <NSThread: 0x7fc82160c390>{number = 2, name = (null)}
任務(wù)2:2, <NSThread: 0x7fc82160c390>{number = 2, name = (null)}
任務(wù)1:0, <NSThread: 0x7fc82160c390>{number = 2, name = (null)}
任務(wù)1:1, <NSThread: 0x7fc82160c390>{number = 2, name = (null)}
任務(wù)1:2, <NSThread: 0x7fc82160c390>{number = 2, name = (null)}

依賴關(guān)系斧账,任務(wù)1依賴任務(wù)2谴返,任務(wù)2完成后才能完成任務(wù)1。但是不能相互依賴其骄,會(huì)造成鎖死亏镰。

最最后:
詳情demo請(qǐng)轉(zhuǎn)接這里

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拯爽,一起剝皮案震驚了整個(gè)濱河市索抓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌毯炮,老刑警劉巖逼肯,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異桃煎,居然都是意外死亡篮幢,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門为迈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來三椿,“玉大人缺菌,你說我怎么就攤上這事∷衙蹋” “怎么了伴郁?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蛋叼。 經(jīng)常有香客問我焊傅,道長(zhǎng),這世上最難降的妖魔是什么狈涮? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任狐胎,我火速辦了婚禮,結(jié)果婚禮上歌馍,老公的妹妹穿的比我還像新娘握巢。我一直安慰自己,他們只是感情好骆姐,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布镜粤。 她就那樣靜靜地躺著,像睡著了一般玻褪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上公荧,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天带射,我揣著相機(jī)與錄音,去河邊找鬼循狰。 笑死窟社,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绪钥。 我是一名探鬼主播灿里,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼程腹!你這毒婦竟也來了匣吊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤寸潦,失蹤者是張志新(化名)和其女友劉穎色鸳,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體见转,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡命雀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了斩箫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吏砂。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡撵儿,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狐血,到底是詐尸還是另有隱情统倒,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布氛雪,位于F島的核電站房匆,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏报亩。R本人自食惡果不足惜浴鸿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望弦追。 院中可真熱鬧岳链,春花似錦、人聲如沸劲件。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽零远。三九已至苗分,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間牵辣,已是汗流浹背摔癣。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留纬向,地道東北人择浊。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像逾条,于是被迫代替她去往敵國(guó)和親琢岩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

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