GCD学习总结

GCD概述:

OC:

/*
 GCD:Grand Central Dispatch 牛X的中枢调度器,C语言编写
 GCD:自动管理线程的生命周期,(创建, 调度任务, 销毁线程)
 
 任务:block (1.定制任务)
 队列:queue (2.任务添加到队列)
 
GCD自动从队列queue中取出任务block执行,遵循FIFO原则,先进先出
 
任务block执行方式:
    同步的(synchronous ['sɪŋkrənəs]):不能开新线程
        dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
    异步的(asynchronous [e'sɪŋkrənəs]):能开新线程
        dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
 
 队列queue:
    并发队列(Concurrent Dispatch Queue):
        [DISPATCH_QUEUE_CONCURRENT];
        让多个任务并发执行,自动开启多个线程同时执行任务;
        该功能只在异步函数(dispatch_async)下有效;
    串行队列(Serial Dispatch Queue):
        [DISPATCH_QUEUE_SERIAL];
        让任务顺序执行;
 
 队列queue的创建:
    并发队列:
        方式1.dispatch_queue_create(const char *label, dispatch_queue_attr_a attr)
            label:表示该队列的名字(标识), C语言中的字符串,创建的时候直接"abcde";
            attr:表示队列属性,设置并发or串行,此处使用并发(DISPATCH_QUEUE_CONCURRENT)
        方式2:获取全局并发队列
            dispatch_get_global_queue(dispatch_queue_priority_t priority, unsigned long flags);
            priority:队列的优先级(高,默认,低,后台)
            flags:此参数暂时无用,用0即可
    串行队列:
        方式1.dispatch_queue_create(const char *label, dispatch_queue_attr_a attr)
            label:表示该队列的名字(标识);
            attr:表示队列属性,设置并发or串行,此处使用串行(DISPATCH_QUEUE_SERIAL or NULL)
        方式2:使用主队列,与主线程相关联的队列
            主队列是GCD自带的一种特殊的串行队列;该队列中的任务,都会在主线程中执行;
            dispatch_get_main_queue();
*/
相关练习:
#pragma mark - 并发队列,同步任务: 没有开启新线程,任务按添加顺序依次执行;
- (void)concurrentSync {
    // A.创建并发队列concurrentQueue:
    char *queueName = "ConcurrentQueue";
    dispatch_queue_t concurrentQueue = dispatch_queue_create(queueName, DISPATCH_QUEUE_CONCURRENT);
    
    // B.创建任务block
    // 方式一: 定义一个block类型,命名为TestBlock1,然后只用该类型声明变量block1
    // 1.定义一个block的类型,返回值void,参数为空,命名为Block1,(类似于 int),
    typedef void (^TestBlock1)();
    // 2.使用Block1类型定义一个变量block, 同时做赋值操作,赋值的内容为后面的代码段(^{...})
    TestBlock1 block1 = ^{
        // 这是里block中的操作
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    // 方式二: 直接定义一个名为block的block2变量
    void (^block2)() = ^{
        // 这是里block中的操作
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    
    // C.给并发队列concurrentQueue,添加同步任务dispatch_sync
    // 方式1: block1变量
    dispatch_sync(concurrentQueue, block1);
    // 方式2: block2变量
    dispatch_sync(concurrentQueue, block2);
    // 方式3: 直接添加block
    dispatch_sync(concurrentQueue, ^{
        // 这是里block中的操作
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block--3---%@", [NSThread currentThread]);
        }
    });
}

#pragma mark - 并发队列,异步任务: 开启新线程,任务并发执行
- (void)concurrentAsync {
    // 1.创建并发队列 DISPATCH_QUEUE_CONCURRENT
    char *queueName = "ConcurrentQueue";
    dispatch_queue_t concurrentQueue = dispatch_queue_create(queueName, DISPATCH_QUEUE_CONCURRENT);
    
    // 2.创建任务block
    typedef void (^TestBlock)();
    TestBlock block = ^{
        // 这是里block中的操作
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        // 这是里block中的操作
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    // 3.并发队列concurrent,添加异步任务async;
    dispatch_async(concurrentQueue, block);
    dispatch_async(concurrentQueue, block2);
    dispatch_async(concurrentQueue, ^{
        // 这是里block中的操作
        for (int i = 0; i < 5; i++) {
            NSLog(@"---3---%@", [NSThread currentThread]);
        }
    });
    
}

#pragma mark - 全局队列,同步任务: 没有开启新线程,任务按添加顺序依次执行;
- (void)globalSync {
    //全局队列的优先级
#define DISPATCH_QUEUE_PRIORITY_HIGH 2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
    typedef long dispatch_queue_priority_t;
    
    // 1.获取全局队列 DISPATCH_QUEUE_PRIORITY_DEFAULT or 0 都可以
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 2.创建任务block
    typedef void (^TestBlock1)();
    TestBlock1 block1 = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    
    // 3.给全局队列globalQueue,添加同步任务dispatch_sync
    dispatch_sync(globalQueue, block1);
    dispatch_sync(globalQueue, block2);
    dispatch_sync(globalQueue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block--3---%@", [NSThread currentThread]);
        }
    });
    
}
#pragma mark - 全局队列,异步任务: 开启新线程,任务并发执行;
- (void)globalAsync {
    // 1.获取全局队列 DISPATCH_QUEUE_PRIORITY_DEFAULT or 0 都可以
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    // 2.创建任务
    typedef void (^TestBlock)();
    TestBlock block = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    // 3.全局队列globalQueue,添加异步任务;
    dispatch_async(globalQueue, block);
    dispatch_async(globalQueue, block2);
    dispatch_async(globalQueue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---3---%@", [NSThread currentThread]);
        }
    });
}

#pragma mark - 串行队列,同步任务: 没有开启新线程,任务按添加顺序依次执行;
- (void)serialSync {
    char *queueName = "SerialQueue";
    // 串行队列 DISPATCH_QUEUE_SERIAL or NULL
    dispatch_queue_t serialQueue = dispatch_queue_create(queueName, DISPATCH_QUEUE_SERIAL);
    
    // 创建任务block
    typedef void (^TestBlock1)();
    TestBlock1 block1 = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    
    // 给串行队列serialQueue,添加同步任务dispatch_sync
    dispatch_sync(serialQueue, block1);
    dispatch_sync(serialQueue, block2);
    dispatch_sync(serialQueue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block--3---%@", [NSThread currentThread]);
        }
    });
    
}

#pragma mark - 串行队列,异步任务: 开启新线程,任务按添加顺序依次执行;
- (void)serialAsync {
    // 1.创建队列queue
    char *queueName = "SerialQueue";
    dispatch_queue_t serialQueue = dispatch_queue_create(queueName, NULL);
    
    // 2.创建任务block
    typedef void (^TestBlock1)();
    TestBlock1 block1 = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    
    // 3.串行队列serialQueue, 添加异步任务
    dispatch_async(serialQueue, block1);
    dispatch_async(serialQueue, block2);
    dispatch_async(serialQueue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block--3---%@", [NSThread currentThread]);
        }
    });
}

#pragma mark - 主队列, 同步任务: 死锁
- (void)mainSync {
    NSLog(@"%s", "主队列mai zhuduilie, 同步任务sync tongburenwu, 会造成死锁 huizaochengsisuo");
    // 1.获得主队列main
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    
    // 2.创建任务block
    typedef void (^TestBlock1)();
    TestBlock1 block1 = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    
    // 3.给主队列mainQueue,添加同步任务dispatch_sync
    dispatch_sync(mainQueue, block1);
    dispatch_sync(mainQueue, block2);
    dispatch_sync(mainQueue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block--3---%@", [NSThread currentThread]);
        }
    });
    // 死锁导致block中的内容都不会执行
}

/*
 GCD Queue 分为三种:
 1,The main queue:主队列,主线程就是在个队列中。
 2,Global queues: 全局并发队列。
 3,用户队列:是用函数 dispatch_queue_create 创建的自定义队列
 
 dispatch_sync 和 dispatch_async 区别:
 dispatch_async(queue,block) async 异步队列,dispatch_async 函数会立即返回, block会在后台异步执行。
 dispatch_sync(queue,block) sync 同步队列,dispatch_sync 函数不会立即返回,及阻塞当前线程,等待block同步执行完成。
 
 分析:
 在主线程中,即dispatch_get_main_queue()中,执行到sync时向dispatch_get_main_queue()插入同步block1.
 sync会等到后面block1执行完成才返回,sync又在dispatch_get_main_queue() 队列中,它是串行队列,sync是后加入的,
 前一个是主线程,所以sync想执行block必须等待主线程执行完成,主线程等待sync返回,去执行后续内容。
 造成死锁,sync等待main执行完成,mian等待sync函数返回。
 */

#pragma mark - 主队列,异步任务: 没有开启新线程,任务按添加顺序依次执行;
- (void)mainAsync {
    // 1.获取主队列main
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    // 2.创建任务block
    typedef void (^TestBlock1)();
    TestBlock1 block1 = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    
    // 3.给主队列mainQueue,添加异步任务dispatch_async
    dispatch_async(mainQueue, block1);
    dispatch_async(mainQueue, block2);
    dispatch_async(mainQueue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block--3---%@", [NSThread currentThread]);
        }
    });
}

#pragma mark -
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    /***********************************************************/
    // 定义block的两种方式之一:
    // 定义
    // 参考范例,返回值int,参数(int, int)(没有参数名,匿名),名称Test
    typedef int (^Test1)(int, int);
    // 使用Test初始化一个变量test
    Test1 test1 ;
    // 实现
    test1 = ^(int x, int y) {
        return  x + y;
    };
    // 调用
    int result = test1(1, 2); //result = 3;
    NSLog(@"%d", result);
    
    /////////
    
    // 初始化变量,实现,同时进行
    Test1 test = ^(int x, int y) {
        return  x + y;
    };
    // 调用
    NSLog(@"%d", test(100, 200));
    
    /***********************************************************/
    // 定义block的两种方式之二:
    // 定义,实现,合并进行
    // 直接定义一个变量test2,参数(int, int)(没有参数名,匿名),名称Test
    int (^test2)(int, int) = ^(int x, int y){
        return x + y;
    };
    NSLog(@"%d", test2(10, 20)); //result = 30;
    /***********************************************************/
}

Swift 3.0:

/**
 GCD:Grand Central Dispatch 牛X的中枢调度器
 GCD:自动管理线程的生命周期,(创建, 调度任务, 销毁线程)
 
 任务:闭包closure or DispatchWorkItem
 队列:DispatchQueue
 
 GCD自动从队列中取出任务执行,遵循FIFO原则,先进先出
 
 任务执行方式:
    同步(synchronous ['sɪŋkrənəs]):不能开新线程
        DispatchQueue.global().sync {
            // 同步执行
        }
    异步(asynchronous [e'sɪŋkrənəs]):能开新线程
        DispatchQueue.global().async {
            // code
            DispatchQueue.main.async {
                // 主线程中
            }
        }
 
 队列DispatchQueue:
    DispatchQueue的默认初始化方法创建的就是一个串行队列,如果要创建并发的队列,在attributes中声明concurrent。
    label:表示该队列的名字(标识);
    attributes:表示队列属性,默认为串行,
    同步队列
        let serialQueue = DispatchQueue(label: "QueueName")
        让任务顺序执行;
    主队列
        let mainQueue = DispatchQueue.main
 
    并发队列
        let concurrentQueue = DispatchQueue(label: "QueueName", attributes: .concurrent)
        让多个任务并发执行,自动开启多个线程同时执行任务;
    全局并发队列
        let globalQueue = DispatchQueue.global(qos: .default)
        let globalQueue = DispatchQueue.global()
        // global 有默认的参数default, 如需改变优先级,则输入对应的枚举即可
 
 */
相关练习:
    // MARK: - 并发Concurrent,同步sync,没有开启新线程,任务在主队列main依次执行;
    func concurrentSync() -> Void {
        // 创建并发队列
        let concurrentQueue = DispatchQueue(label: "ConcurrentQueue", attributes: .concurrent)
        
        // 任务类型
        typealias Task = () -> Void
        // Task类型的变量
        let task1: Task
        // 任务实现
        task1 = {
            print("concurrentSync task1...", Thread.current)
        }
        
        let task2: () -> Void = {
            print("concurrentSync task2...", Thread.current)
        }
        
        // 并发队列Concurrent,同步sync执行
        concurrentQueue.sync(execute: task1) // main
        concurrentQueue.sync(execute: task2) // main
        concurrentQueue.sync {
            print("concurrentSync task3...", Thread.current)
        } // main
    }
    
    // MARK: - 并发Concurrent,异步async,开启新线程,任务并发执行;
    func concurrentAsync() -> Void {
        // 队列(并发concurrent)
        let concurrentQueue = DispatchQueue(label: "ConcurrentQueue", attributes: .concurrent)
        // 任务(闭包 or block)
        typealias Task = () -> Void
        let task1: Task = {
            print("concurrentAsync-task1...", Thread.current)
        }
        let task2: () -> Void = {
            print("concurrentAsync-task2...", Thread.current)
        }
        // 并发,异步
        concurrentQueue.async(execute: task1) // new 1
        concurrentQueue.async(execute: task2) // new 2
        concurrentQueue.async {
            print("concurrentAsync-task3...", Thread.current)
        } // new 3
    }
    
    // MARK: - 全局global,同步sync,没有开启新线程,任务在主队列main依次执行;
    func globalSync() -> Void {
        typealias Task = () -> Void
        let task1: Task = {
            print("globalSync...task1...", Thread.current)
        }
        let task2: () -> Void = {
            print("globalSync...task2...", Thread.current)
        }
        
        /**
         * global优先级的新旧枚举值对应
         * DISPATCH_QUEUE_PRIORITY_HIGH:         .userInitiated
         * DISPATCH_QUEUE_PRIORITY_DEFAULT:      .default
         * DISPATCH_QUEUE_PRIORITY_LOW:          .utility
         * DISPATCH_QUEUE_PRIORITY_BACKGROUND:   .background
         */
        // public class func global(qos: DispatchQoS.QoSClass = default) -> DispatchQueue
        // global 有默认的参数default, 如需改变优先级,则输入对应的枚举即可
        DispatchQueue.global(qos: .userInteractive).sync(execute: task1) // main 1
        DispatchQueue.global(qos: .userInteractive).sync(execute: task2) // main 2
        DispatchQueue.global(qos: .userInteractive).sync {
            print("globalSync...task3...", Thread.current)
            
        } // main 3
    }
    
    // MARK: - 全局global,异步async,开启新线程,任务并发执行;
    func globalAsync() -> Void {
        typealias Task = () -> Void
        let task1: Task = {
            print("globalAsync...task1...", Thread.current)
        }
        let task2: Task = {
            print("globalAsync...task2...", Thread.current)
        }
        DispatchQueue.global().async(execute: task1) // new 1
        DispatchQueue.global().async(execute: task2) // new 2
        DispatchQueue.global().async {
            print("globalAsync...task3...", Thread.current)
        } // new 3
    }
    
    /// 线程任务
    typealias ThreadTask = () -> Void

    // MARK: - 串行serial,同步sync,没有开启新线程,任务按顺序执行;
    func serialSync() -> Void {
        // 队列
        let serialQueue = DispatchQueue(label: "SerialQueue")
        // 任务
        let task1: ThreadTask = {
            print("serialSync...task1...", Thread.current)
        }
        let task2: ThreadTask = {
            print("serialSync...task2...", Thread.current)
        }
        let task3: ThreadTask = {
            print("serialSync...task3...", Thread.current)
        }
        // 串行,同步
        serialQueue.sync(execute: task1) // main 1
        serialQueue.sync(execute: task2) // main 2
        serialQueue.sync(execute: task3) // main 3
    }
    
    // MARK: - 串行Serial,异步async,开启新线程,任务按顺序执行
    func serialAsync() -> Void {
        // 队列
        let serialQueue = DispatchQueue(label: "SerialQueue")
        // 任务
        let task1: ThreadTask = {
            print("serialSync...task1...", Thread.current)
        }
        let task2: ThreadTask = {
            print("serialSync...task2...", Thread.current)
        }
        let task3: ThreadTask = {
            print("serialSync...task3...", Thread.current)
        }
        // 串行,异步
        serialQueue.async(execute: task1) // new 1
        serialQueue.async(execute: task2) // new 2
        serialQueue.async(execute: task3) // new 3
    }
    
    // MARK: - 主队列main,同步sync,死锁
    func mainSync() -> Void {
        // 队列
        let mainQueue = DispatchQueue.main
        // 任务
        let task1: ThreadTask = {
            print("serialSync...task1...", Thread.current)
        }
        let task2: ThreadTask = {
            print("serialSync...task2...", Thread.current)
        }
        let task3: ThreadTask = {
            print("serialSync...task3...", Thread.current)
        }
        // 主队列,同步
        mainQueue.sync(execute: task1) // 死锁 x
        mainQueue.sync(execute: task2) // x
        DispatchQueue.main.sync(execute: task3) // x
    }
    
    // MARK: - 主队列main,异步async,不开启新线程,任务依次执行
    func mainAsync() -> Void {
        let mainQueue = DispatchQueue.main
        
        let task1: ThreadTask = {
            print("serialSync...task1...", Thread.current)
        }
        let task2: ThreadTask = {
            print("serialSync...task2...", Thread.current)
        }
        let task3: ThreadTask = {
            print("serialSync...task3...", Thread.current)
        }
        
        mainQueue.async(execute: task1) // main 1
        mainQueue.async(execute: task2) // main 2
        DispatchQueue.main.async(execute: task3) // main 3
    }
    
    // MARK: - 闭包测试
    func closureTest() -> Void {
        // 闭包回顾
        /***********************************************************/
        // 定义, 有3+参, 有返回值
        typealias Test = (Int, Int, Int) -> Int
        // 声明变量test1
        var test1: Test
        // 实现
        test1 = { x, y, z in
            // 闭包中的操作
            print("有3+参, 有返回值 test1...111")
            return x + y + z
        }
        // 调用
        print("test1...", test1(1, 2, 3))
        
        // 声明,实现
        let test2: Test = {
            // 闭包中的操作
            print("有3+参, 有返回值 test2...222")
            return $0 + $1 + $2
        }
        // 调用
        print("test2...", test2(10, 20, 30))
        /***********************************************************/
        // 定义, 有2参, 有返回值
        var test3: (Int, Int) -> Int
        // 实现
        test3 = (+)
        // 调用
        print("有2参, 有返回值 test3...", test3(100, 200))
        /***********************************************************/
        // 定义,无参,有返回值
        var test4: () -> Int
        // 实现
        test4 = {
            // 闭包中的操作
            print("无参,有返回值 test4... 444")
            return 12345
        }
        // 调用
        print("test4...", test4())
        /***********************************************************/
        // 定义,无参,无返回值
        let test5: () -> Void = {
            // 相关操作
            print("无参,有返回值 test5... 555")
        }
        test5()
        /***********************************************************/
    }

参考资料:
http://www.jianshu.com/p/fc78dab5736f
http://www.jianshu.com/p/28044b17f94b
https://www.logcg.com/archives/2040.html
https://github.com/future-challenger/Swift3.0/blob/master/GCD/README.md
https://my.oschina.net/doxing/blog/618132
http://v.youku.com/v_show/id_XMTU5MDg1MTE0NA==.html
http://v.youku.com/v_show/id_XMTU5MDg0OTY1Mg==.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容

  • GCD GCD的全称是Grand Central Dispatch,字面意思就是“极好的中枢调度器”,它能通过队列...
    cr7aa阅读 436评论 0 0
  • 1、前言 GCD的学习中一定要理解任务,同步、异步,串行、并发的概念,以及他们之间相互结合运行的效果。 2、GCD...
    SuperDawn_0828阅读 348评论 0 1
  • 许久许久未见的人 原来真的梦不到 孤独 和谁的相处都无法避免 可能就是某个时刻的无解和凉意 这很平常呀 所以不 过...
    写在沙上阅读 196评论 0 0
  • Eimon阅读 175评论 0 0
  • 再见你时,一如从前的模样。光洁的额头,姣好的面容,笑时露出一排整齐的牙齿。和年少时分毫未变。 走进你的房...
    土lemon阅读 632评论 0 2