NSOperation 簡(jiǎn)介

一、簡(jiǎn)介

除了次泽,NSThread和GCD實(shí)現(xiàn)多線(xiàn)程,配合使用NSOperation和NSOperationQueue也能實(shí)現(xiàn)多線(xiàn)程編程

NSOperation和NSOperationQueue實(shí)現(xiàn)多線(xiàn)程的具體步驟

1席爽、先將需要執(zhí)行的操作封裝到一個(gè)NSOperation的子類(lèi)對(duì)象中

實(shí)際上意荤,NSOperation是個(gè)抽象類(lèi),并不具備封裝操作的能力,必須使用它的子類(lèi)

2只锻、然后將NSOperation對(duì)象添加到NSOperationQueue中

3玖像、系統(tǒng)會(huì)自動(dòng)將NSOperationQueue中的NSOperation取出來(lái)

4、將取出的NSOperation封裝的操作放到一條新線(xiàn)程中執(zhí)行

二齐饮、NSOperation

如上所示:要實(shí)現(xiàn)多線(xiàn)程捐寥,必須要將執(zhí)行的操作封裝到NSOperation的子類(lèi)對(duì)象中,那么NSOperation的子類(lèi)有哪些沈矿?

1上真、使用NSOperation子類(lèi)的方式有3種

NSInvocationOperation

NSBlockOperation

自定義子類(lèi)繼承NSOperation咬腋,實(shí)現(xiàn)NSOperation的某些方法

NSInvocationOperation

創(chuàng)建NSInvocationOperation對(duì)象

-(id)initWithTarget:(id)target selector:(SEL)selector object:(id)arg;

NSInvocationOperation將操作封裝成SEL羹膳,只有將NSInvocationOperation添加到NSOperationQueue中,才會(huì)異步執(zhí)行操作根竿。

- (void)test {

// 1.將操作封裝到Operation中

NSInvocationOperation*op1 = [[NSInvocationOperationalloc] initWithTarget:selfselector:@selector(demo) object:nil];

// 2.執(zhí)行封裝的操作

// 如果直接執(zhí)行NSInvocationOperation中的操作, 那么默認(rèn)會(huì)在主線(xiàn)程中執(zhí)行

//[op1 start];

// 創(chuàng)建隊(duì)列

NSOperationQueue*queue = [[NSOperationQueuealloc] init];

//將任務(wù)加入到隊(duì)列 任務(wù)會(huì)自動(dòng)開(kāi)啟

[queue addOperation:op1];

}

NSBlockOperation

創(chuàng)建NSBlockOperation 對(duì)象

+ (instancetype)blockOperationWithBlock:(void (^)(void))block;

NSBlockOperation將任務(wù)封裝成一個(gè)block陵像,這種方式看起來(lái)更方便就珠。當(dāng)然,你還可以調(diào)用-addExecutionBlock:方法醒颖,添加另一個(gè)任務(wù)妻怎。

注意點(diǎn):只要NSBlockOperation封裝的操作數(shù) >1,直接調(diào)用start方法泞歉,就會(huì)異步執(zhí)行操作逼侦,但是默認(rèn)的初始化的block任務(wù)是在主線(xiàn)程中執(zhí)行。

- (void)test {

NSBlockOperation*blockOperation = [NSBlockOperationblockOperationWithBlock:^{

NSLog(@"開(kāi)始執(zhí)行任務(wù)");

}];

[blockOperation addExecutionBlock:^{

NSLog(@"開(kāi)始下一個(gè)執(zhí)行任務(wù)");

}];

//如果不將NSBlockOperation添加到隊(duì)列中腰耙,而是直接調(diào)用start方法榛丢,那么默認(rèn)初始化時(shí)的任務(wù)執(zhí)行在主線(xiàn)程中画机,而通過(guò)addExecutionBlock方法添加的任務(wù)都執(zhí)行在子線(xiàn)程中呛谜。

//[blockOperation start];

// 創(chuàng)建隊(duì)列

NSOperationQueue*queue = [[NSOperationQueuealloc] init];

//將任務(wù)加入到隊(duì)列 任務(wù)會(huì)自動(dòng)開(kāi)啟

[queue addOperation: blockOperation];

}

自定義 NSOperation

首先需要繼承NSOperation嗦明,然后實(shí)現(xiàn)某些方法蚣抗。

我們有兩種方法來(lái)實(shí)現(xiàn)自定義operation侯繁,一種是通過(guò)重寫(xiě)main方法鱼鼓,一種是通過(guò)重寫(xiě)start方法帮寻,前者實(shí)現(xiàn)起來(lái)更簡(jiǎn)單悍赢,我們不需要管理一些屬性狀態(tài)援制,例如isExecuting或者isFinished等戏挡。當(dāng)main方法執(zhí)行結(jié)束的時(shí)候,這個(gè)operation就結(jié)束了晨仑。另外一種是重寫(xiě)start方法增拥,但是這種方法需要你管理各種屬性的狀態(tài),雖然麻煩寻歧,但是相對(duì)靈活掌栅。如果你同時(shí)實(shí)現(xiàn)start和main方法,則優(yōu)先使用start方法码泛。因?yàn)榈谝环N方法比較簡(jiǎn)單猾封,我們這里以第二種方法來(lái)自定義operation。

首先噪珊,父類(lèi)提供了一系列的getter方法晌缘,用以獲知任務(wù)的狀態(tài)。

@property (readonly, getter=isReady) BOOL ready

此屬性表明NSOperation是否已經(jīng)準(zhǔn)備好開(kāi)始執(zhí)行任務(wù)了痢站,如果返回false磷箕,NSOperation的之后的方法都不會(huì)執(zhí)行。通常情況下阵难,自定義operation岳枷,我們可以利用它來(lái)讓調(diào)用者必須滿(mǎn)足一定的條件才能執(zhí)行任務(wù)。

@property (readonly, getter=isExecuting) BOOL executing

是否正在執(zhí)行。

@property (readonly, getter=isFinished) BOOL finished

任務(wù)是否完成

@property (readonly, getter=isCancelled) BOOL cancelled

任務(wù)是否取消

@property (readonly, getter=isConcurrent) BOOL concurrent

表示是否異步執(zhí)行任務(wù)

自定義operation如下

MyOperation.h

@interfaceMyOperation:NSOperation

+ (instancetype)crateOperationWithMoney:(int)money;

@end

MyOperation.m

#import"MyOperation.h"

#import

@interfaceMyOperation()

@property(nonatomic,assign)intmoney;

@property(nonatomic,assign)BOOLcancelled;

@property(nonatomic,assign)BOOLexecuting;

@property(nonatomic,assign)BOOLfinished;

@property(nonatomic,assign)BOOLconcurrent;

@property(nonatomic,assign)BOOLasynchronous;

@end

@implementationMyOperation

@synthesizecancelled;

@synthesizeexecuting;

@synthesizefinished;

@synthesizeconcurrent;

@synthesizeasynchronous;

+ (instancetype)crateOperationWithMoney:(int)money {

MyOperation *operation = [[MyOperation alloc] init];

operation.money = money;

returnoperation;

}

- (BOOL)isReady {

//只有當(dāng)金額大于等于100的時(shí)候才執(zhí)行任務(wù)

return_money >=100;

}

- (void)start {

//判斷任務(wù)狀態(tài)

if(self.isExecuting ||self.isCancelled ||self.isFinished) {

return;

}

NSLog(@"%@--%@開(kāi)始花錢(qián)",self.name,[NSThreadcurrentThread]);

self.executing =YES;

while(self.money >0){

self.money--;

NSLog(@"%@花錢(qián)了%d",self.name,self.money);

}

//執(zhí)行完畢

self.finished =YES;

self.executing =NO;

}

- (BOOL)isExecuting {

returnself.executing;

}

- (void)cancel {

NSLog(@"%@%@取消",[NSThreadcurrentThread],self.name);

self.finished =YES;

self.cancelled =YES;

self.executing =NO;

}

- (BOOL)isCancelled {

returnself.cancelled;

}

- (BOOL)isFinished {

returnself.finished;

}

- (BOOL)isConcurrent {

returnself.concurrent;

}

- (BOOL)isAsynchronous {

returnself.asynchronous;

}

- (void)dealloc {

NSLog(@"%@dealloc",self.name);

}

@end

這僅僅是一個(gè)簡(jiǎn)單的實(shí)例空繁,真正的項(xiàng)目中還需要打磨殿衰,如果沒(méi)有特殊的要求,還是使用系統(tǒng)提供的比較好盛泡。

添加依賴(lài)

目的 -> NSOperation之間可以設(shè)置依賴(lài)來(lái)保證執(zhí)行順序

例如:一定要讓操作A執(zhí)行完后闷祥,才能執(zhí)行操作B,可以這么寫(xiě)

[operationB addDependency:operationA];

例如我們通過(guò)不同的線(xiàn)程下載圖片 當(dāng)都下載完成以后在合成圖片

#import"ViewController.h"

@interfaceViewController()

@property(weak,nonatomic)IBOutletUIImageView*imageView;

@end

@implementationViewController

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event

{

NSOperationQueue*queue = [[NSOperationQueuealloc] init];

NSOperationQueue*queue2 = [[NSOperationQueuealloc] init];

__blockUIImage*image1 =nil;

__blockUIImage*image2 =nil;

// 1.開(kāi)啟一個(gè)線(xiàn)程下載第一張圖片

NSOperation*op1 = [NSBlockOperationblockOperationWithBlock:^{

NSURL*url = [NSURLURLWithString:@"http://cdn.cocimg.com/assets/images/logo.png?v=201510272"];

NSData*data = [NSDatadataWithContentsOfURL:url];

// 2.生成下載好的圖片

UIImage*image = [UIImageimageWithData:data];

image1 = image;

}];

// 2.開(kāi)啟一個(gè)線(xiàn)程下載第二長(zhǎng)圖片

NSOperation*op2 = [NSBlockOperationblockOperationWithBlock:^{

NSURL*url = [NSURLURLWithString:@"https://www.baidu.com/img/bd_logo1.png"];

NSData*data = [NSDatadataWithContentsOfURL:url];

// 2.生成下載好的圖片

UIImage*image = [UIImageimageWithData:data];

image2 = image;

}];

// 3.開(kāi)啟一個(gè)線(xiàn)程合成圖片

NSOperation*op3 = [NSBlockOperationblockOperationWithBlock:^{

UIGraphicsBeginImageContext(CGSizeMake(200,200));

[image1 drawInRect:CGRectMake(0,0,100,200)];

[image2 drawInRect:CGRectMake(100,0,100,200)];

UIImage*newImage =UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

// 4.回到主線(xiàn)程更新UI

[[NSOperationQueuemainQueue] addOperationWithBlock:^{

NSLog(@"回到主線(xiàn)程更新UI");

self.imageView.image = newImage;

}];

}];

// 監(jiān)聽(tīng)任務(wù)是否執(zhí)行完畢

op1.completionBlock = ^{

NSLog(@"第一張圖片下載完畢");

};

op2.completionBlock = ^{

NSLog(@"第二張圖片下載完畢");

};

// 添加依賴(lài)

// 只要添加了依賴(lài), 那么就會(huì)等依賴(lài)的任務(wù)執(zhí)行完畢, 才會(huì)執(zhí)行當(dāng)前任務(wù)

// 注意:

// 1.添加依賴(lài), 不能添加循環(huán)依賴(lài)

// 2.NSOperation可以跨隊(duì)列添加依賴(lài)

[op3 addDependency:op1];

[op3 addDependency:op2];

// 將任務(wù)添加到隊(duì)列中

[queue addOperation:op1];

[queue addOperation:op2];

[queue2 addOperation:op3];

}

@end

三傲诵、NSOperationQueue

NSOperation可以調(diào)用start方法來(lái)執(zhí)行操作凯砍,但是默認(rèn)是同步執(zhí)行的。將NSOperation添加到NSOperationQueue中拴竹,系統(tǒng)會(huì)自動(dòng)異步調(diào)用NSOperation的start方法或者main方法來(lái)執(zhí)行任務(wù)果覆。

NSOperationQueue提供了三種添加任務(wù)的方法:

- (void)addOperation:(NSOperation *)op將NSOperation對(duì)象添加到隊(duì)列中

- (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait將NSOperation對(duì)象數(shù)組添加到隊(duì)列中,wait表示是否阻塞當(dāng)前隊(duì)列殖熟,YES表明以后添加的任務(wù)只能在ops中的所有任務(wù)執(zhí)行完成以后才會(huì)執(zhí)行局待,NO表示不阻塞當(dāng)前隊(duì)列

- (void)addOperationWithBlock:(void (^)(void))block將一個(gè)block添加到任務(wù)中。

這里有幾點(diǎn)需要注意的菱属,添加的任務(wù)一定不能是正在執(zhí)行的或者已經(jīng)完成的钳榨,可通過(guò)executing和finished來(lái)判斷。不能重復(fù)添加一個(gè)operation到同一個(gè)隊(duì)列中纽门,否則會(huì)報(bào)NSInvalidArgumentException異常薛耻。

再來(lái)看看NSOperationQueue的屬性:

operations當(dāng)前正在執(zhí)行或者等待執(zhí)行的任務(wù)的集合,如果一個(gè)任務(wù)執(zhí)行完畢赏陵,會(huì)從中刪除饼齿。

operationCount當(dāng)前隊(duì)列中的任務(wù)數(shù)(正在執(zhí)行或者等待執(zhí)行)

maxConcurrentOperationCount最大并發(fā)數(shù),默認(rèn)是-1蝙搔,即無(wú)限大缕溉,如果設(shè)置為1,那么當(dāng)前隊(duì)列即為串行隊(duì)列吃型,但不能設(shè)置成0证鸥,如果設(shè)置成0,那么當(dāng)前的所有任務(wù)都不能執(zhí)行勤晚。

name隊(duì)列的名字

當(dāng)然枉层,NSOperationQueue也提供了取消操作,

- (void)cancelAllOperations赐写,此方法會(huì)取消所有未執(zhí)行的操作鸟蜡。內(nèi)部實(shí)現(xiàn)是分別調(diào)用任務(wù)的cancel方法。但是已經(jīng)執(zhí)行的操作將會(huì)繼續(xù)執(zhí)行挺邀。另外此方法并不會(huì)將取消的操作從隊(duì)列中移除揉忘。但是實(shí)際卻移除了跳座,這是因?yàn)镹SInvocationOperation和NSBlockOperation內(nèi)部自己管理了finish狀態(tài),在cancel方法中會(huì)將當(dāng)前任務(wù)的finish設(shè)置為YES癌淮。

- (void)waitUntilAllOperationsAreFinished阻塞當(dāng)前任務(wù)隊(duì)列躺坟。




NSOperation的作用

配合使用NSOperation和NSOperationQueue也能實(shí)現(xiàn)多線(xiàn)程編程

NSOperation和NSOperationQueue實(shí)現(xiàn)多線(xiàn)程的具體步驟

先將需要執(zhí)行的操作封裝到一個(gè)NSOperation對(duì)象中

然后將NSOperation對(duì)象添加到NSOperationQueue中

系統(tǒng)會(huì)自動(dòng)將NSOperationQueue中的NSOperation取出來(lái)

將取出的NSOperation封裝的操作放到一條新線(xiàn)程中執(zhí)行

NSOperation的子類(lèi)

NSOperation是個(gè)抽象類(lèi)沦补,并不具備封裝操作的能力乳蓄,必須使用它的子類(lèi)

使用NSOperation子類(lèi)的方式有3種

NSInvocationOperation

NSBlockOperation

自定義子類(lèi)繼承NSOperation,實(shí)現(xiàn)內(nèi)部相應(yīng)的方法

創(chuàng)建NSInvocationOperation對(duì)象

-(id)initWithTarget:(id)targetselector:(SEL)selobject:(id)arg;

調(diào)用start方法開(kāi)始執(zhí)行操作

-(void)start;

一旦執(zhí)行操作夕膀,就會(huì)調(diào)用target的sel方法

注意

默認(rèn)情況下虚倒,調(diào)用了start方法后并不會(huì)開(kāi)一條新線(xiàn)程去執(zhí)行操作,而是在當(dāng)前線(xiàn)程同步執(zhí)行操作

只有將NSOperation放到一個(gè)NSOperationQueue中产舞,才會(huì)異步執(zhí)行操作

創(chuàng)建NSBlockOperation對(duì)象

+(id)blockOperationWithBlock:(void(^)(void))block;

通過(guò)addExecutionBlock:方法添加更多的操作

-(void)addExecutionBlock:(void(^)(void))block;

注意:只要NSBlockOperation封裝的操作數(shù) >1魂奥,就會(huì)異步執(zhí)行操作

NSOperationQueue的作用

NSOperation可以調(diào)用start方法來(lái)執(zhí)行任務(wù),但默認(rèn)是同步執(zhí)行的

如果將NSOperation添加到NSOperationQueue(操作隊(duì)列)中易猫,系統(tǒng)會(huì)自動(dòng)異步執(zhí)行NSOperation中的操作

添加操作到NSOperationQueue中

-(void)addOperation:(NSOperation*)op;

-(void)addOperationWithBlock:(void(^)(void))block;

什么是并發(fā)數(shù)

同時(shí)執(zhí)行的任務(wù)數(shù)

比如耻煤,同時(shí)開(kāi)3個(gè)線(xiàn)程執(zhí)行3個(gè)任務(wù),并發(fā)數(shù)就是3

最大并發(fā)數(shù)的相關(guān)方法

-(NSInteger)maxConcurrentOperationCount;

-(void)setMaxConcurrentOperationCount:(NSInteger)cat;

取消隊(duì)列的所有操作

-(void)cancelAllOperations;

提示:也可以調(diào)用NSOperation的-(void)cancel方法取消單個(gè)操作

暫停和恢復(fù)隊(duì)列

-(void)setSuspended:(BOOL)b;// YES代表暫停隊(duì)列准颓,NO代表恢復(fù)隊(duì)列

-(BOOL)isSuspended;

Operation之間可以設(shè)置依賴(lài)來(lái)保證執(zhí)行順序

比如一定要讓操作A執(zhí)行完后哈蝇,才能執(zhí)行操作B,可以這么寫(xiě)

[operationBaddDependency:operationA];// 操作B依賴(lài)于操作A

可以在不同queue的NSOperation之間創(chuàng)建依賴(lài)關(guān)系

可以監(jiān)聽(tīng)一個(gè)操作的執(zhí)行完畢

-(void(^)(void))completionBlock;

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

自定義NSOperation的步驟很簡(jiǎn)單

重寫(xiě)-(void)main方法攘已,在里面實(shí)現(xiàn)想執(zhí)行的任務(wù)

重寫(xiě)-(void)main方法的注意點(diǎn)

自己創(chuàng)建自動(dòng)釋放池(因?yàn)槿绻钱惒讲僮髋谏猓瑹o(wú)法訪(fǎng)問(wèn)主線(xiàn)程的自動(dòng)釋放池)

經(jīng)常通過(guò)-(BOOL)isCancelled方法檢測(cè)操作是否被取消,對(duì)取消做出響應(yīng)

一個(gè)操作需要取消時(shí)样勃,必須等這個(gè)操作的任務(wù)執(zhí)行完畢吠勘,或者在這個(gè)操作的內(nèi)容不斷的判斷是否有取消操作。

總結(jié):

回主線(xiàn)刷新UI

[[NSOperationQueue mainQueue] addOprationWithBblock:^{回主線(xiàn)程刷新UI}];

------------------------------------------------------------

操作:NSOperation峡眶、NSInvocationOperation剧防、NSBlockOpearation。

隊(duì)列:NSOperationQueue

當(dāng)使用NSInvocationOperation時(shí)

操作加入隊(duì)列時(shí):(注意:當(dāng)前線(xiàn)程決定currentQueue在主隊(duì)列還是在子隊(duì)列)

1辫樱、不需要調(diào)用start方法诵姜,如果調(diào)用start方法會(huì)崩潰。

2搏熄、在主隊(duì)列時(shí)(和當(dāng)前線(xiàn)程無(wú)關(guān))在主線(xiàn)程執(zhí)行

3棚唆、在自定義隊(duì)列時(shí)=> [[NSOperationQueue alloc]init](和當(dāng)前線(xiàn)程無(wú)關(guān))在子線(xiàn)程中執(zhí)行

不加入隊(duì)列時(shí):

1、需要調(diào)用start方法心例,在當(dāng)前線(xiàn)程中執(zhí)行(主=主宵凌,子=子)

所以:隊(duì)列決定了線(xiàn)程在主線(xiàn)程還是子線(xiàn)程中執(zhí)行

所在隊(duì)列執(zhí)行線(xiàn)程.png

當(dāng)是用NSBlockOperation時(shí)

不加入隊(duì)列,:需要調(diào)用start方法

直接用NSBlockOperation封裝的任務(wù)會(huì)在當(dāng)前線(xiàn)程中執(zhí)行(主=主止后,子=子)瞎惫。

當(dāng)使用addExecutionBlock添加任務(wù)后溜腐,也就是當(dāng)任務(wù)的個(gè)數(shù)大于1,那么之后的任務(wù)會(huì)在子線(xiàn)程中執(zhí)行瓜喇,NSBlockOperation封裝的任務(wù)還是會(huì)在主線(xiàn)程中執(zhí)行挺益。

加入隊(duì)列:不需要調(diào)用start方法

會(huì)在子線(xiàn)程中執(zhí)行任務(wù)。

NSINvocationOperation和NSBlockOpertaion和自定義的NSOperation都可以同時(shí)加入到同一個(gè)隊(duì)列中乘寒,不需要調(diào)用start方法望众,并且都是在子線(xiàn)程中執(zhí)行。

自定義NSOPeration需要將操作封裝到自定的這個(gè)對(duì)象中伞辛,通過(guò)重寫(xiě)mian方法來(lái)實(shí)現(xiàn)封裝任務(wù)烂翰。

異步串行執(zhí)行任務(wù)的方式

NSOpration實(shí)現(xiàn)異步串行執(zhí)行的方式:

1、設(shè)置最大并發(fā)數(shù)為1蚤氏。

2甘耿、不設(shè)置并發(fā)數(shù)時(shí),設(shè)置任務(wù)之間的依賴(lài)竿滨。

而GCD實(shí)現(xiàn)異步串行執(zhí)行的方式:

1佳恬、異步+自定義串行隊(duì)列(非主隊(duì)列)

2、dispatch_barrier_async柵欄函數(shù)

NSOperation比GCD的好處

1于游、能通過(guò)KVO鍵值觀察者來(lái)實(shí)時(shí)監(jiān)控operation的狀態(tài)(是否執(zhí)行毁葱,是否取消),而GCD無(wú)法通過(guò)KVO來(lái)實(shí)時(shí)監(jiān)控曙砂。通過(guò)completBlock來(lái)回調(diào)已經(jīng)執(zhí)行完畢头谜。

2、NSOperation能通過(guò)設(shè)置依賴(lài)鸠澈,使任務(wù)之間有先后順序柱告。GCD可以通過(guò)柵欄函數(shù)來(lái)實(shí)現(xiàn)。

3笑陈、NSOperation能設(shè)置并行隊(duì)列中任務(wù)(NSOperation)的優(yōu)先級(jí)(設(shè)置NSOperation在queue中的優(yōu)先級(jí),可以改變操作的執(zhí)?優(yōu)先級(jí))(優(yōu)先級(jí)的作用是讓優(yōu)先級(jí)高的線(xiàn)程需要cpu時(shí)就能夠得到cpu际度,而不是讓優(yōu)先級(jí)低的線(xiàn)程無(wú)法運(yùn)行,并且可能不止一個(gè)CPU,說(shuō)明:優(yōu)先級(jí)高的任務(wù)涵妥,調(diào)用的幾率會(huì)更大)

NSOperation是將任務(wù)放入隊(duì)列中來(lái)執(zhí)行的乖菱。

GCD是將任務(wù)放入隊(duì)列中,通過(guò)同步異步函數(shù)來(lái)執(zhí)行(可以多個(gè)同步異步函數(shù))蓬网。

而GCD是設(shè)置不同任務(wù)隊(duì)列(queue)的優(yōu)先級(jí)窒所,要實(shí)現(xiàn)block的優(yōu)先級(jí),需要很多代碼帆锋。

GCD更簡(jiǎ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)店門(mén)摄乒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)悠反,“玉大人,你說(shuō)我怎么就攤上這事缺狠∥噬鳎” “怎么了萍摊?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵挤茄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我冰木,道長(zhǎng)穷劈,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任踊沸,我火速辦了婚禮歇终,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逼龟。我一直安慰自己评凝,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布腺律。 她就那樣靜靜地躺著奕短,像睡著了一般。 火紅的嫁衣襯著肌膚如雪匀钧。 梳的紋絲不亂的頭發(fā)上翎碑,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音之斯,去河邊找鬼日杈。 笑死,一個(gè)胖子當(dāng)著我的面吹牛佑刷,可吹牛的內(nèi)容都是我干的莉擒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼瘫絮,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼涨冀!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起檀何,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蝇裤,失蹤者是張志新(化名)和其女友劉穎廷支,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(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
  • 文/蒙蒙 一济竹、第九天 我趴在偏房一處隱蔽的房頂上張望痕檬。 院中可真熱鬧,春花似錦送浊、人聲如沸梦谜。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)唁桩。三九已至,卻和暖如春浴讯,著一層夾襖步出監(jiān)牢的瞬間朵夏,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 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)容