多線程網(wǎng)絡(luò)02

1 GCD柵欄函數(shù)

柵欄函數(shù)用戶控制隊(duì)列里異步函數(shù)的的執(zhí)行順序澳窑。
注:柵欄函數(shù)不能使用全局并發(fā)隊(duì)列斧散,需要用自己創(chuàng)建的并發(fā)隊(duì)列。

- (void)barrier {
    // 創(chuàng)建并發(fā)隊(duì)列
    dispatch_queue_t queue = dispatch_queue_create("com.zyx.barrier", 0);
    // 創(chuàng)建人物照捡,添加到隊(duì)列
    dispatch_async(queue, ^{
        NSLog(@"download1-----");
    });
    dispatch_async(queue, ^{
        NSLog(@"download2-----");
    });
    // 柵欄函數(shù)颅湘,用于控制先執(zhí)行人物1和2 再執(zhí)行任務(wù)3
    dispatch_barrier_async(queue, ^{
        NSLog(@"++++++++++++++++++++++");
    });
    dispatch_async(queue, ^{
        NSLog(@"download3-----");
    });
}
2 GCD快速迭代

開子線程和主線程一起完成遍歷任務(wù),任務(wù)的執(zhí)行是并發(fā)的栗精。

- (void)applyDemo {
    /*
     參數(shù)1:遍歷次數(shù)
     參數(shù)2:隊(duì)列(并發(fā)隊(duì)列)
     參數(shù)3:索引
     */
    dispatch_apply(20, dispatch_get_global_queue(0, 0), ^(size_t index) {
        NSLog(@"%zd---%@",index,[NSThread currentThread]);
    });
}
// 文件剪切操作
- (void)moveFile {
    // 1 拿到要移動文件路徑
    NSString *from = @"/Users/apple/Desktop/from";
    // 2 獲取目標(biāo)文件路徑
    NSString *to = @"/Users/apple/Desktop/to";
    // 3 得到目錄下所有文件
    NSArray *filePath = [[NSFileManager defaultManager] subpathsAtPath:from];
    NSLog(@"%@",filePath);
    // 4 移動文件到指定目錄
    NSInteger count = filePath.count;
    dispatch_apply(count, dispatch_get_global_queue(0, 0), ^(size_t index) {
        // 4.1 拼接文件全路徑
        NSString *fullPath = [from stringByAppendingPathComponent:filePath[index]];
        NSString *toFullPath = [to stringByAppendingPathComponent:filePath[index]];
        NSError *error;
        [[NSFileManager defaultManager] moveItemAtPath:fullPath toPath:toFullPath error:&error];
    });
}
3 GCD隊(duì)列組的使用
// 隊(duì)列組
- (void)group1 {
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        NSLog(@"download1-----");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"download2-----");
    });
    dispatch_group_async(group, queue, ^{
        NSLog(@"download3-----");
    });
    // 攔截通知,當(dāng)當(dāng)隊(duì)列里面的任務(wù)執(zhí)行完畢后進(jìn)入該方法,該方法不會阻塞
    dispatch_group_notify(group, queue, ^{
        NSLog(@"task is over");
    });
    
    // 該方法是阻塞的
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    NSLog(@"---end---");
    
}

- (void)group2 {
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_group_t group = dispatch_group_create();
    // 該方法后面的異步任務(wù)會被納入到隊(duì)列組的監(jiān)聽范圍中
    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{
        NSLog(@"download1-----");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{
        NSLog(@"download2-----");
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_group_async(group, queue, ^{
        NSLog(@"download3-----");
        dispatch_group_leave(group);
    });
    // 攔截通知悲立,當(dāng)當(dāng)隊(duì)列里面的任務(wù)執(zhí)行完畢后進(jìn)入該方法
    dispatch_group_notify(group, queue, ^{
        NSLog(@"task is over");
    });
}
4 GCD異步函數(shù)方式2
- (void)asyncConcurrent {
    /*
     參數(shù)1:隊(duì)列
     參數(shù)2:參數(shù)3函數(shù)的參數(shù)
     參數(shù)3:函數(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 *params) {
    NSLog(@"--%s--",__func__);
}
5 單例模式通用宏
#define SingleH(name) + (instancetype)share##name;

#if __has_feature(objc_arc) // ARC模式
#define SinglM(name) static id _instance;\
+ (instancetype)allocWithZone:(struct _NSZone *)zone { \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [super allocWithZone:zone]; \
    }); \
    return _instance; \
} \
\
+ (instancetype)share##name { \
    return [[self alloc] init]; \
} \
\
- (id)copyWithZone:(NSZone *)zone { \
    return _instance; \
} \
\
- (id)mutableCopyWithZone:(NSZone *)zone { \
    return _instance; \
} 
#else // MRC模式
#define SinglM(name) static id _instance;\
+ (instancetype)allocWithZone:(struct _NSZone *)zone { \
    static dispatch_once_t onceToken; \
    dispatch_once(&onceToken, ^{ \
        _instance = [super allocWithZone:zone]; \
    }); \
    return _instance; \
} \
\
+ (instancetype)share##name { \
    return [[self alloc] init]; \
} \
\
- (id)copyWithZone:(NSZone *)zone { \
    return _instance; \
} \
\
- (id)mutableCopyWithZone:(NSZone *)zone { \
    return _instance; \
} \
- (oneway void)release { \
    \
} \
\
- (instancetype)retain { \
    return _instance; \
} \
\
- (NSUInteger)retainCount { \
    return MAXFLOAT; \
}
#endif
6 NSOperation基本概念

6.1 簡介

  • NSOperation的作用
    配合使用NSOperation和NSOperationQueue也能實(shí)現(xiàn)多線程編程
  • NSOperation和NSOperationQueue實(shí)現(xiàn)多線程的具體步驟
    1)先將需要執(zhí)行的操作封裝到一個NSOperation對象中
    2)然后將NSOperation對象添加到NSOperationQueue中
    3)系統(tǒng)會自動將NSOperationQueue中的NSOperation取出來
    4)將取出的NSOperation封裝的操作放到一條新的線程中執(zhí)行

6.2 NSOperation的子類

  • NSOperation是個抽象類,并不具備封裝操作的能力薪夕,必須要使用它的子類
  • 使用NSOperation紫烈的方式有3種
    1)NSInvocationOperation
    2)NSBlockOperation
    3)自定義子類集成NSOperation脚草,實(shí)現(xiàn)內(nèi)部相應(yīng)的方法
- (void)invocationOperation { // 不會開啟新的線程
    /*
     參數(shù)1:目標(biāo)對象
     參數(shù)2:執(zhí)行的操作方法
     參數(shù)3:方法的參數(shù)
     */
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil];
    [op1 start];
    
    NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil];
    [op2 start];
    
    
    NSInvocationOperation *op3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil];
    [op3 start];
}

- (void)download1 {
    NSLog(@"%s--%@",__func__,[NSThread currentThread]);
}

- (void)blockOperation {
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1--%@",[NSThread currentThread]);
    }];
    [op1 start];
    
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1--%@",[NSThread currentThread]);
    }];
    [op2 start];
    
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1--%@",[NSThread currentThread]);
    }];
    
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1--%@",[NSThread currentThread]);
    }];
    [op4 start];
    
    NSBlockOperation *op5 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1--%@",[NSThread currentThread]);
    }];
    [op5 start];
    
    NSBlockOperation *op6 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1--%@",[NSThread currentThread]);
    }];
    [op6 start];
    
    // 如果block操作里面的任務(wù)超過1個,那么會開啟多個線程原献,但不一定是子線程
    [op3 addExecutionBlock:^{
        NSLog(@"4--%@",[NSThread currentThread]);
    }];
    
    [op3 addExecutionBlock:^{
        NSLog(@"5--%@",[NSThread currentThread]);
    }];
    
    [op3 addExecutionBlock:^{
        NSLog(@"6--%@",[NSThread currentThread]);
    }];
    
    [op3 start];
}
7 NSOperationQueue的基本使用
- (void)blockOperationWithQueue {
    // 1 創(chuàng)建操作
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1--%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2--%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"3--%@",[NSThread currentThread]);
    }];
    
    // 2 創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 3 將操作添加到隊(duì)列
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
    
    // 簡便方法
    [queue addOperationWithBlock:^{
        NSLog(@"4--%@",[NSThread currentThread]);
    }];
}

- (void)invocationOperationWithQueue {
    // 1 創(chuàng)建操作
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil];
    NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil];
    NSInvocationOperation *op3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil];
    
    // 2 創(chuàng)建隊(duì)列
    /*
     NSOperationQueue
     主隊(duì)列:和GCD主隊(duì)列一樣馏慨,也是串行隊(duì)列 [NSOperationQueue mainQueue]
     非主隊(duì)列:[[NSOperationQueue alloc] init]
     非主隊(duì)列非常特殊,又分為串行隊(duì)列和并發(fā)隊(duì)列姑隅,默認(rèn)是并發(fā)隊(duì)列
     */
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 3 添加操作到隊(duì)列中執(zhí)行
    [queue addOperation:op1]; // 內(nèi)部已經(jīng)調(diào)用的start方法
    [queue addOperation:op2];
    [queue addOperation:op3];
}
8 自定義NSOperation
- (void)customOperationWithQueue {
    // 創(chuàng)建操作
    ZYXOperation *op1 = [[ZYXOperation alloc] init];
    // 創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    // 添加操作到隊(duì)列
    [queue addOperation:op1];
}

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface ZYXOperation : NSOperation

@end

NS_ASSUME_NONNULL_END

#import "ZYXOperation.h"

@implementation ZYXOperation
- (void)main { // 自定義操作需要實(shí)現(xiàn)該方法写隶,明確要執(zhí)行什么操作
    NSLog(@"main---%@",[NSThread currentThread]);
}
@end
9 NSOperation的其他用法

9.1 如何設(shè)置串行隊(duì)列

- (void)test {
    // 1 創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 默認(rèn)是并發(fā)隊(duì)列
    // maxConcurrentOperationCount 最大執(zhí)行并發(fā)操作數(shù)量
    // maxConcurrentOperationCount默認(rèn)值為-1 表示不受限制
    // maxConcurrentOperationCount = 0 不會執(zhí)行操作
    // maxConcurrentOperationCount = 1 串行隊(duì)列
    // maxConcurrentOperationCount >= 2 并發(fā)隊(duì)列
    queue.maxConcurrentOperationCount = 1;
    // 2 創(chuàng)建操作
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1--%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2--%@",[NSThread currentThread]);
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"3--%@",[NSThread currentThread]);
    }];
    // 添加操作到隊(duì)列
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
}

9.2 隊(duì)列任務(wù)的開始、暫停讲仰、繼續(xù)以及取消操作

- (IBAction)startOperation:(UIButton *)sender {
    [self test];
}

// 暫停任務(wù)
- (IBAction)pauseOperation:(UIButton *)sender {
    // 暫停是可以恢復(fù)的
    // 隊(duì)列中的任務(wù)也是有狀態(tài)的:已執(zhí)行慕趴、正在執(zhí)行、未執(zhí)行
    // 不能取消隊(duì)列里面正在執(zhí)行的任務(wù)
    [self.queue setSuspended:YES];
}

// 繼續(xù)任務(wù)
- (IBAction)restartOperation:(UIButton *)sender {
    [self.queue setSuspended:NO];
}

// 取消任務(wù)
- (IBAction)cancelOperation:(UIButton *)sender {
    // 取消是不可以恢復(fù)的
    [self.queue cancelAllOperations];
}

- (void)test {
    // 1 創(chuàng)建隊(duì)列
    self.queue = [[NSOperationQueue alloc] init]; // 默認(rèn)是并發(fā)隊(duì)列
    // maxConcurrentOperationCount 最大執(zhí)行并發(fā)操作數(shù)量
    // maxConcurrentOperationCount默認(rèn)值為-1 表示不受限制
    // maxConcurrentOperationCount = 0 不會執(zhí)行操作
    // maxConcurrentOperationCount = 1 串行隊(duì)列
    // maxConcurrentOperationCount >= 2 并發(fā)隊(duì)列
    self.queue.maxConcurrentOperationCount = 1;
    // 2 創(chuàng)建操作
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 10000; i++) {
            NSLog(@"1--%d--%@",i,[NSThread currentThread]);
        }
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 10000; i++) {
            NSLog(@"2--%d--%@",i,[NSThread currentThread]);
        }
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 10000; i++) {
            NSLog(@"3--%d--%@",i,[NSThread currentThread]);
        }
    }];
    // 添加操作到隊(duì)列
    [self.queue addOperation:op1];
    [self.queue addOperation:op2];
    [self.queue addOperation:op3];
}

9.3 自定義NSOperation的取消操作

- (IBAction)startOperation:(UIButton *)sender {
    // 1 創(chuàng)建自定義操作
    ZYXOperation *op1 = [[ZYXOperation alloc] init];
    // 2 創(chuàng)建隊(duì)列
    self.queue = [[NSOperationQueue alloc] init];
    // 3 添加操作到隊(duì)列
    [self.queue addOperation:op1];
}

// 暫停任務(wù)
- (IBAction)pauseOperation:(UIButton *)sender {
    // 暫停是可以恢復(fù)的
    // 隊(duì)列中的任務(wù)也是有狀態(tài)的:已執(zhí)行鄙陡、正在執(zhí)行冕房、未執(zhí)行
    // 不能取消隊(duì)列里面正在執(zhí)行的任務(wù)
    [self.queue setSuspended:YES];
}

// 繼續(xù)任務(wù)
- (IBAction)restartOperation:(UIButton *)sender {
    [self.queue setSuspended:NO];
}

// 取消任務(wù)
- (IBAction)cancelOperation:(UIButton *)sender {
    // 取消是不可以恢復(fù)的
    [self.queue cancelAllOperations];
}

- (void)main {
    for (int i = 0; i < 10000; i++) {
        NSLog(@"1--%d---%@",i,[NSThread currentThread]);
    }
    
    // 官方推薦方式,也可以放在循環(huán)里面趁矾,但這樣會消耗性能
    if (self.isCancelled) {
        return;
    }
    
    for (int i = 0; i < 10000; i++) {
        NSLog(@"2--%d---%@",i,[NSThread currentThread]);
    }
    
    if (self.isCancelled) {
        return;
    }
    
    for (int i = 0; i < 10000; i++) {
        NSLog(@"3--%d---%@",i,[NSThread currentThread]);
    }
}
10 NSOperation操作依賴和監(jiān)聽

10.1 操作依賴和監(jiān)聽

- (void)operationDepency {
    // 1 創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSOperationQueue *queue2 = [[NSOperationQueue alloc] init];
    // 2 創(chuàng)建操作
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1--%@",[NSThread currentThread]);
    }];
    
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
         NSLog(@"2--%@",[NSThread currentThread]);
    }];
    
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
         NSLog(@"3--%@",[NSThread currentThread]);
    }];
    
    
    // 操作依賴
    op3.completionBlock = ^{
        NSLog(@"task is over--%@",[NSThread currentThread]);
    };
    // 添加操作依賴  不僅同一個隊(duì)列可以耙册,而且不同隊(duì)列之間亦可以
    // 注意:不能添加循環(huán)依賴,這樣會導(dǎo)致不會執(zhí)行任何操作 依賴可以跨隊(duì)列
    [op1 addDependency:op2];
    [op2 addDependency:op3];
    
    // 添加操作到隊(duì)列
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue2 addOperation:op3];
}
11 NSOperation實(shí)現(xiàn)線程間通信

11.1 下載圖片demo

- (void)downloadImage {
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSString *str = @"http://cdn.duitang.com/uploads/item/201504/19/20150419H4413_XdNfU.thumb.700_0.png";
        NSURL *url = [NSURL URLWithString:str];
        NSData *data = [[NSData alloc] initWithContentsOfURL:url];
        UIImage *image = [UIImage imageWithData:data];
        //更新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.imageView.image = image;
        }];
    }];
    [queue addOperation:op1];
}

11.2 下載并合成圖片

- (void)downloadCombineImage {
    // 創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    __block UIImage *image1;
    __block UIImage *image2;
    // 下載圖片1
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSString *str = @"http://cdn.duitang.com/uploads/item/201504/19/20150419H4413_XdNfU.thumb.700_0.png";
        NSURL *url = [NSURL URLWithString:str];
        NSData *data = [[NSData alloc] initWithContentsOfURL:url];
        image1 = [UIImage imageWithData:data];
    }];
    
    // 下載圖片2
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSString *str = @"http://5b0988e595225.cdn.sohucs.com/images/20171210/362dcd1c009842ff99b33f5d51bbfb80.jpeg";
        NSURL *url = [NSURL URLWithString:str];
        NSData *data = [[NSData alloc] initWithContentsOfURL:url];
        image2 = [UIImage imageWithData:data];
        
    }];
    
    // 合成圖片
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        // 獲取上下文
        UIGraphicsBeginImageContext(CGSizeMake(200, 200));
        // 畫image1
        [image1 drawInRect:CGRectMake(0, 0, 100, 200)];
        // 畫image2
        [image2 drawInRect:CGRectMake(100, 0, 100, 200)];
        // 獲取圖片
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        // 關(guān)閉上下文
        UIGraphicsEndImageContext();
        //更新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.imageView.image = image;
        }];
    }];
    
    // 添加依賴
    [op3 addDependency:op1];
    [op3 addDependency:op2];
    
    // 添加操作到隊(duì)列
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
}
12 多線程補(bǔ)充

12.1 在使用NSOperation和NSOperationQueue時毫捣,將操作添加到隊(duì)列時觅玻,會自動條用operation的start方法。而在調(diào)用start方法時培漏,會去調(diào)用main方法溪厘。
12.2 在使用NSThread時,初始化時牌柄,可以直接使用init進(jìn)行初始化畸悬,然后再其main方法里面添加任務(wù)。

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self customThread2];
}

- (void)customThread {
    ZYXOperation *op1 = [[ZYXOperation alloc] init];
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [queue addOperation:op1];
}

- (void)customThread2 {
    ZYXThread *op1 = [[ZYXThread alloc] init];
    [op1 start];
}

#import "ZYXOperation.h"

@implementation ZYXOperation
- (void)start {
    NSLog(@"start--start");
    [super start];
    NSLog(@"start--end");
}

- (void)main {
    NSLog(@"main--start");
    [super main];
    NSLog(@"main--end");
}
@end

#import "ZYXThread.h"

@implementation ZYXThread
- (void)main {
    NSLog(@"%s---%@",__func__,[NSThread currentThread]);
}
@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末珊佣,一起剝皮案震驚了整個濱河市蹋宦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咒锻,老刑警劉巖冷冗,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異惑艇,居然都是意外死亡蒿辙,警方通過查閱死者的電腦和手機(jī)拇泛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來思灌,“玉大人俺叭,你說我怎么就攤上這事√┏ィ” “怎么了熄守?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長耗跛。 經(jīng)常有香客問我裕照,道長,這世上最難降的妖魔是什么调塌? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任晋南,我火速辦了婚禮,結(jié)果婚禮上烟阐,老公的妹妹穿的比我還像新娘搬俊。我一直安慰自己,他們只是感情好蜒茄,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布唉擂。 她就那樣靜靜地躺著,像睡著了一般檀葛。 火紅的嫁衣襯著肌膚如雪玩祟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天屿聋,我揣著相機(jī)與錄音空扎,去河邊找鬼。 笑死润讥,一個胖子當(dāng)著我的面吹牛转锈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播楚殿,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼撮慨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了脆粥?” 一聲冷哼從身側(cè)響起砌溺,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎变隔,沒想到半個月后规伐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡匣缘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年猖闪,在試婚紗的時候發(fā)現(xiàn)自己被綠了鲜棠。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡萧朝,死狀恐怖岔留,靈堂內(nèi)的尸體忽然破棺而出夏哭,到底是詐尸還是另有隱情检柬,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布竖配,位于F島的核電站何址,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏进胯。R本人自食惡果不足惜用爪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望胁镐。 院中可真熱鬧偎血,春花似錦、人聲如沸盯漂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽就缆。三九已至帖渠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間竭宰,已是汗流浹背空郊。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留切揭,地道東北人狞甚。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像廓旬,于是被迫代替她去往敵國和親哼审。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

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