D30:Block, GCD方式實現(xiàn)多線程

一. block實現(xiàn)反向傳值

二. block封裝下載類型

三. GCD基本概念

GCD是iOS4之后的技術(shù), 是基于C語言來實現(xiàn)的, 速度更快, 效率更高
通常使用GCD來實現(xiàn)多線程

四. GCD的使用

五. GCD下載圖片

六. GCD擴展

七. 抓包(選項目)

這里使用paros.jar來抓包
下載安裝JAVA SDK環(huán)境: Oracle官網(wǎng): Downloads - JAVA SE - SDK - MACOS 64bit
如果還是無法打開paros.jar, 請將paros相關(guān)文件放至在英文目錄下

獲取電腦在當(dāng)前局域網(wǎng)內(nèi)的IP: 192.168.80.15
保證手機和電腦在同一個網(wǎng)段下
a) 連上同一個wifi
b) 在電腦上設(shè)一個熱點, 手機連接該熱點

手機進(jìn)入Wi-Fi界面, 進(jìn)入連接的網(wǎng)絡(luò), 滑到最下方, 設(shè)置HTTP代理, 改為手動模式, 服務(wù)器設(shè)為電腦的IP, 設(shè)置一個較大的端口, 如8080或8888(charles抓包軟件默認(rèn)端口)
此時打開paros.jar即可檢測到設(shè)備的網(wǎng)絡(luò)活動

a)打開iTunes捺信,進(jìn)入apple store界面
b)選中一個應(yīng)用酌媒,點擊進(jìn)入應(yīng)用的詳情介紹界面
c)點擊“獲取”按鈕,下載這個應(yīng)用
d)下載完成之后迄靠,找到下載的這個應(yīng)用秒咨,右擊選擇“show In Finder”,顯示ipa文件
e)右擊ipa文件->打開方式->歸檔工具
f)在生成的文件夾下面,有一個payload文件夾掌挚,選中文件夾下面的文件,右擊->顯示包內(nèi)容,這樣就能夠看到應(yīng)用所用的資源文件

1)html文件,three20第三方庫,直接用UIWebView顯示這個鏈接
2)有些應(yīng)用Andriod和iphone的接口不一樣


一. block實現(xiàn)反向傳值

1. 實現(xiàn)常規(guī)的導(dǎo)航控制器push跳轉(zhuǎn)頁面功能
//
//  ViewController.m
//  01_BlockReverseValues

#import "ViewController.h"
#import "MyUtility.h"
#import "DetailViewController.h"

@interface ViewController ()

@property (nonatomic, strong) UILabel *label;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    // 顯示文字
    _label = [[UILabel alloc] initWithFrame:CGRectMake(50, 100, 100, 40)];
    [self.view addSubview:_label];
    
    // 創(chuàng)建按鈕
    UIButton *btn = [MyUtility createButtonWithFrame:CGRectMake(100, 200, 80, 40) title:@"跳轉(zhuǎn)" backgroundImageName:nil target:self action:@selector(gotoNextPage)];
    [self.view addSubview:btn];
    
}

- (void)gotoNextPage
{
    DetailViewController *dvc = [[DetailViewController alloc] init];
    [self.navigationController pushViewController:dvc animated:YES];
    
    };
}

//
//  DetailViewController.h
//  01_BlockReverseValues  

#import <UIKit/UIKit.h>

@interface DetailViewController : UIViewController

@end

#import "DetailViewController.h"
#import "MyUtility.h"

@implementation DetailViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    
    [self createBtns];
}

- (void)createBtns
{
    UIButton *btn1 = [MyUtility createButtonWithFrame:CGRectMake(100, 100, 80, 40) title:@"Button1" backgroundImageName:nil target:self action:@selector(clickBtn:)];
    UIButton *btn2 = [MyUtility createButtonWithFrame:CGRectMake(100, 200, 80, 40) title:@"Button2" backgroundImageName:nil target:self action:@selector(clickBtn:)];
    UIButton *btn3 = [MyUtility createButtonWithFrame:CGRectMake(100, 300, 80, 40) title:@"Button3" backgroundImageName:nil target:self action:@selector(clickBtn:)];
    [self.view addSubview:btn1];
    [self.view addSubview:btn2];
    [self.view addSubview:btn3];
}
    
@end
2. 增加利用block傳值的代碼
  1. ViewController的gotoNextPage方法
    - (void)gotoNextPage
    {
    DetailViewController *dvc = [[DetailViewController alloc] init];
    [self.navigationController pushViewController:dvc animated:YES];

         // 給block賦值
         __weak ViewController *weakSelf = self;
         dvc.clickBlock = ^(NSString *title){
             // 修改Label上面的文字
             weakSelf.label.text = title;
         };
     }
    
  2. 為DetailViewController類增加一個block屬性, 在點擊按鈕執(zhí)行的方法中由該block屬性來處理需要反向傳遞的值

     @interface DetailViewController : UIViewController
     
     // block傳值
     @property (nonatomic, copy) void (^clickBlock)(NSString *param);
     
     @end
    
     @implementation DetailViewController
     
     - (void)clickBtn:(UIButton *)sender
     {
         NSString *title = sender.currentTitle;
         // [sender titleForState:UIControlStateNormal];
         
         // 使用
         if (self.clickBlock) {
             self.clickBlock(title);
         }
     }  
    

二. block封裝下載類型

1. 按照常規(guī)步驟編寫MyDownloader類, 下載結(jié)束和下載失敗的代碼暫不處理
//
//  MyDownloader.h
//  02_BlockDownloader

#import <Foundation/Foundation.h>

@interface MyDownloader : NSObject <NSURLConnectionDataDelegate, NSURLConnectionDelegate>

// 下載數(shù)據(jù)
- (void)downloadWithURLString:(NSString *)urlString

@end  
  
//
//  MyDownloader.m
//  02_BlockDownloader
  
#import "MyDownloader.h"

@implementation MyDownloader
{
    // 下載數(shù)據(jù)
    NSMutableData *_receiveData;
    // 下載對象
    NSURLConnection *_connection;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        // 初始化下載數(shù)據(jù)
        _receiveData = [NSMutableData data];
    }
    return self;
}

- (void)downloadWithURLString:(NSString *)urlString
{
    _connection = [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]  delegate:self];
}

#pragma mark - NSURLConnection
// 下載失敗
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    
}

// 每次數(shù)據(jù)下載回來后
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [_receiveData appendData:data];
}

// 請求響應(yīng)
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [_receiveData setLength:0];
}

// 下載成功
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    
}

@end
2. 修改MyDownload類: 修改下載數(shù)據(jù)的公開方法, 令其包含參數(shù)類型為NSData(下載結(jié)束所得的數(shù)據(jù)類型)的block參數(shù)和 參數(shù)類型為NSError(下載失敗所得的數(shù)據(jù)類型的)block參數(shù), 并各自增加該類型的block作為成員變量
// 把變量名去掉就是block的類型
// 下載數(shù)據(jù)
- (void)downloadWithURLString:(NSString *)urlString finishBlock:(void (^)(NSData *data))finishBlock failBlock:(void (^)(NSError *error))failBlock;  

//
//  MyDownloader.m
//  02_BlockDownloader

#import "MyDownloader.h"

@implementation MyDownloader
{
    …………………………………………………………………………………………
        
    // 聲明
    // 下載成功
    void (^_finishBlock)(NSData *data);
    // 下載失敗
    void (^_failBlock)(NSError *error);
}

…………………………………………………………………………………………

- (void)downloadWithURLString:(NSString *)urlString finishBlock:(void (^)(NSData *))finishBlock failBlock:(void (^)(NSError *))failBlock
{
    // block的賦值
    // 給block成員變量賦值
    if (_finishBlock != finishBlock) {
        _finishBlock = nil;
        _finishBlock = finishBlock;
    }
    
    if (_failBlock != failBlock) {
        _failBlock = nil;
        _failBlock = failBlock;
    }
    
    _connection = [NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]  delegate:self];
}

#pragma mark - NSURLConnection
// 下載失敗
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    // 調(diào)用
    if (_failBlock) {
        _failBlock(error);
    }
}

// 每次數(shù)據(jù)下載回來后
…………………………………………………………………………………………

// 請求響應(yīng)
…………………………………………………………………………………………

// 下載成功
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // 調(diào)用
    if (_finishBlock) {
        _finishBlock(_receiveData);
    }
}

@end
3. 在ViewController.m中導(dǎo)入MyDownloader類使用
#import "ViewController.h"
#import "MyDownloader.h"

// 下載鏈接
#define kLimitUrl (@"http://iappfree.candou.com:8080/free/applications/limited?currency=rmb&page=1")

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    MyDownloader *downloader = [[MyDownloader alloc] init];
    
    [downloader downloadWithURLString:kLimitUrl finishBlock:^(NSData *data) {
        
        // 解析數(shù)據(jù)
        id result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        if ([result isKindOfClass:[NSDictionary class]]) {
            NSDictionary *dict = result;
            
            NSArray *array = dict[@"applications"];
            NSLog(@"%@", array);
        }
        
    } failBlock:^(NSError *error) {
        NSLog(@"%@", error);
    }];
}

三. GCD基本概念

  1. GCD的隊列
  1. 主線程所在的串行隊列
    串行隊列的意思是前面的代碼執(zhí)行完成, 才開始執(zhí)行后面的代碼
    并行隊列是前面的代碼和后面的代碼同時開始執(zhí)行, 并行運行的方式效率更高
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
  2. 全局的并行隊列
  3. 自己創(chuàng)建的隊列:
    • 并行隊列
    • 串行隊列
  1. 怎樣實現(xiàn)線程
  1. 同步的提交(不能讓主線程(串行)同步執(zhí)行一段代碼, 程序會卡死)

  2. 異步的提交

    • (void)viewDidLoad {
      [super viewDidLoad];
      // Do any additional setup after loading the view, typically from a nib.

      // GCD實現(xiàn)多線程是將代碼塊(線程的執(zhí)行體)提交到隊列里面執(zhí)行

      // 1. GCD的隊列
      // 1) 主線程所在的串行隊列
      // 串行隊列的意思是前面的代碼執(zhí)行完成, 才開始執(zhí)行后面的代碼
      // 并行隊列是前面的代碼和后面的代碼同時開始執(zhí)行, 并行運行的方式效率更高
      dispatch_queue_t mainQueue = dispatch_get_main_queue();

      // 2) 全局的并行隊列
      /*
      第一個參數(shù): 隊列的優(yōu)先級
      第二個參數(shù): 是apple預(yù)留的一個參數(shù), 傳0即可
      */
      dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

      // 3) 自己創(chuàng)建的隊列
      /*
      第一個參數(shù): 隊列的標(biāo)識符
      第二個參數(shù): 用來區(qū)分串行還是并行
      DISPATCH_QUEUE_SERIAL 串行
      DISPATCH_QUEUE_CONCURRENT 并行
      */
      // a) 串行隊列
      dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
      // b) 并行隊列
      dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);

      // 2. 怎樣實現(xiàn)線程
      // 1) 同步的提交(不能讓主線程(串行)同步執(zhí)行一段代碼, 程序會卡住直到代碼運行完成)
      /*
      第一個參數(shù): 線程在哪個隊列執(zhí)行
      第二個參數(shù): 代碼塊, 線程的執(zhí)行體
      */
      dispatch_sync(serialQueue, ^{
      for (int i = 0; i < 100; i++) {
      NSLog(@"執(zhí)行了任務(wù)1: %d", i);
      }
      });

      // 2) 異步的提交
      /*
      第一個參數(shù): 線程在哪個隊列執(zhí)行
      第二個參數(shù): 代碼塊, 線程的執(zhí)行體
      */
      dispatch_async(mainQueue, ^{
      for (int i = 0; i < 100; i++) {
      NSLog(@"執(zhí)行了任務(wù)2: %d", i);
      }
      });
      }


四. GCD的使用

1. 以同步的方式向串行隊列提交代碼
/*
 前面的線程執(zhí)行完畢之后, 才開始執(zhí)行后面的線程
 */
- (void)testSyncMethodWithSerialQueue
{
    // 創(chuàng)建一個串行的隊列
    dispatch_queue_t serialQueue = dispatch_queue_create("Queue1", DISPATCH_QUEUE_SERIAL);
    
    // 以同步的方式提交兩個代碼塊
    dispatch_sync(serialQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"%@執(zhí)行了任務(wù)1: %d", [NSThread currentThread], i);
        }
    });
    
    dispatch_sync(serialQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"%@執(zhí)行了任務(wù)2: %d", [NSThread currentThread], i);
        }
    });
}
2. 以同步的方式向并行隊列提交代碼
/*
 前面的線程執(zhí)行完畢之后, 才開始執(zhí)行后面的線程
 */
- (void)testSyncMethodWithConcurrentQueue
{
    // 獲取全局隊列
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 以同步的方式創(chuàng)建兩個代碼塊
    dispatch_sync(globalQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"%@執(zhí)行了任務(wù)1: %d", [NSThread currentThread], i);
        }
    });
    
    dispatch_sync(globalQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"%@執(zhí)行了任務(wù)2: %d", [NSThread currentThread], i);
        }
    });
}
3. 以異步的方式向串行隊列提交代碼
- (void)testAsyncMethodWithserialQueue
{
    // 創(chuàng)建串行隊列
    dispatch_queue_t serialQueue = dispatch_queue_create("queueThree", DISPATCH_QUEUE_SERIAL);
    
    // 異步提交兩個代碼塊
    dispatch_async(serialQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"%@執(zhí)行了任務(wù)1: %d", [NSThread currentThread], i);
        }
    });
    
    dispatch_async(serialQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"%@執(zhí)行了任務(wù)2: %d", [NSThread currentThread], i);
        }
    });
}
4. 以異步的方式向并行隊列提交代碼
- (void)testAsyncMethodWithConcurrentQueue
{
    // 創(chuàng)建并行隊列
    dispatch_queue_t concurrentQueue = dispatch_queue_create("queueFour", DISPATCH_QUEUE_CONCURRENT);
    
    // 異步提交兩段代碼塊
    dispatch_async(concurrentQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"%@執(zhí)行了任務(wù)1: %d", [NSThread currentThread], i);
        }
    });
    
    dispatch_async(concurrentQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"%@執(zhí)行了任務(wù)2: %d", [NSThread currentThread], i);
        }
    });
}

五. GCD下載圖片

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 使用GCD下載圖片
    // @"http://img3.3lian.com/2006/027/08/007.jpg"
    
    // 獲取全局并行隊列
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 向隊列中異步提交代碼塊
    __weak ViewController *weakSelf = self;
    
    dispatch_async(globalQueue, ^{
        
        // 下載圖片
        NSURL *url = [NSURL URLWithString:@"http://img3.3lian.com/2006/027/08/007.jpg"];
        // 下載數(shù)據(jù)
        NSData *data = [NSData dataWithContentsOfURL:url];
        
        // 下載完成后回到主線程修改UI
        dispatch_async(dispatch_get_main_queue(), ^{
            
            UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(40, 100, 240, 320)];
            imageView.image = [UIImage imageWithData:data];
            [weakSelf.view addSubview:imageView];
            
        });
    });
}

六. GCD擴展

1. 代碼執(zhí)行多次
- (void)testMultiTimes
{
    /*
     第一個參數(shù): 執(zhí)行的次數(shù)
     第二個參數(shù): 代碼執(zhí)行體所在的隊列
     第三個參數(shù): 線程的執(zhí)行體(代碼塊)
     */
    dispatch_apply(5, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t time) {
        // time 表示現(xiàn)在執(zhí)行的是第幾次
        NSLog(@"執(zhí)行第%zu次", time);
    });
    /*
     執(zhí)行結(jié)果是無序的
     2015-06-12 14:28:25.975 06_GCDMore[1195:23542] 執(zhí)行第0次
     2015-06-12 14:28:25.975 06_GCDMore[1195:23643] 執(zhí)行第1次
     2015-06-12 14:28:25.975 06_GCDMore[1195:23644] 執(zhí)行第2次
     2015-06-12 14:28:25.976 06_GCDMore[1195:23542] 執(zhí)行第4次
     2015-06-12 14:28:25.975 06_GCDMore[1195:23645] 執(zhí)行第3次
     */
}  
2. 代碼在一段時間之后運行
- (void)testGCDAfter
{
    NSLog(@"now");
    
    // 時間值
    // 十秒之后
    dispatch_time_t t = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 10);
    
    /*
     第一個參數(shù): 線程執(zhí)行的時間
     第二個參數(shù): 線程執(zhí)行的隊列
     第三個參數(shù): 線程的執(zhí)行體
     */
    dispatch_after(t, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"after");
    });
}
3. 代碼在程序運行期間只執(zhí)行一次
// 通常用來實現(xiàn)單例
- (void)testGDCOnlyOnce
{
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        NSLog(@"代碼執(zhí)行1次");
    });
}
4. Group: 在幾個線程都執(zhí)行完成之后需要(才)做一些操作
- (void)testGDCGroup
{
    // 創(chuàng)建一個Group
    dispatch_group_t myGroup = dispatch_group_create();
    
    // 隊列
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 執(zhí)行兩個線程
    /* 
     第一個參數(shù): group
     第二個參數(shù): 隊列
     第三個參數(shù): 線程的執(zhí)行體
     */
    dispatch_group_async(myGroup, globalQueue, ^{
        
        for (int i = 0; i < 100; i++) {
            NSLog(@"執(zhí)行了線程1:%d", i);
        }
        
    });
    
    dispatch_group_async(myGroup, globalQueue, ^{
        
        for (int i = 0; i < 100; i++) {
            NSLog(@"執(zhí)行了線程2:%d", i);
        }
        
    });
    
    // 在兩個線程都執(zhí)行完成之后, 執(zhí)行一些操作
    dispatch_group_notify(myGroup, globalQueue, ^{
        NSLog(@"兩個線程都執(zhí)行完成");
        NSLog(@"%s", __func__);
    });
}
5. 讓所有的線程分成2部分
- (void)testGCDBarrier
{
    // 并行隊列
    // 這種方式只能使用自己創(chuàng)建的并行隊列
    dispatch_queue_t concurrentQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(concurrentQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"執(zhí)行了線程1:%d" ,i);
        }
    });
    
    dispatch_async(concurrentQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"執(zhí)行了線程2:%d" ,i);
        }
    });
    
    dispatch_barrier_async(concurrentQueue, ^{
        NSLog(@"Barrier");
    });
    
    dispatch_async(concurrentQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"執(zhí)行了線程3:%d" ,i);
        }
    });
    
    dispatch_async(concurrentQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"執(zhí)行了線程4:%d" ,i);
        }
    });
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末雨席,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子吠式,更是在濱河造成了極大的恐慌陡厘,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件特占,死亡現(xiàn)場離奇詭異糙置,居然都是意外死亡,警方通過查閱死者的電腦和手機摩钙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門罢低,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人胖笛,你說我怎么就攤上這事网持。” “怎么了长踊?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵功舀,是天一觀的道長。 經(jīng)常有香客問我身弊,道長辟汰,這世上最難降的妖魔是什么列敲? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮帖汞,結(jié)果婚禮上戴而,老公的妹妹穿的比我還像新娘。我一直安慰自己翩蘸,他們只是感情好所意,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著催首,像睡著了一般扶踊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上郎任,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天秧耗,我揣著相機與錄音,去河邊找鬼舶治。 笑死分井,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的歼疮。 我是一名探鬼主播杂抽,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼韩脏!你這毒婦竟也來了缩麸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤赡矢,失蹤者是張志新(化名)和其女友劉穎杭朱,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吹散,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡弧械,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了空民。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刃唐。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖界轩,靈堂內(nèi)的尸體忽然破棺而出画饥,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站润绵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏衔彻。R本人自食惡果不足惜薇宠,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望艰额。 院中可真熱鬧澄港,春花似錦、人聲如沸柄沮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铡溪。三九已至,卻和暖如春泪喊,著一層夾襖步出監(jiān)牢的瞬間棕硫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工袒啼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留哈扮,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓蚓再,卻偏偏與公主長得像滑肉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子摘仅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

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