GCD 卡塔

//
//  ViewController.m
//  GSDDemo
//
//  Created by Code_Hou on 2017/3/30.
//  Copyright © 2017年 侯森魁. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

/*
 开启新的线程需要占用内存空间:
 主线程 在1M左右
 
 每个子线程占用:512KB
 
 */
@implementation ViewController

- (void)test01{
    //1.获取主线程串行队列
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    
    //2.主线程串行队列同步执行任务,在主线程运行时,会产生死锁
        dispatch_sync(mainQueue, ^{
        NSLog(@"MainQueue");
        });
    //程序一直等待状态,block中的代码将执行不到

}

- (void)test02{
    //1.获取主线程串行队列
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    
    //主线程串行队列异步执行、在主线程运行时、不会产生死锁
    dispatch_async(mainQueue, ^{
        NSLog(@"MainQueue");
    });
    //程序正常运行,block中的代码正常运行
    
}

- (void)test03 {
    
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(globalQueue, ^{
    //子线程异步执行下载任务,防止主线程卡顿
        NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
        
        NSError *error;
        
        NSString *htmlData = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];
        if (htmlData) {
            
          dispatch_queue_t mainQueue =    dispatch_get_main_queue();
          //异步返回主线程,根据获取的数据,更新UI
            dispatch_async(mainQueue, ^{
            
            NSLog(@"更新UI");
            
            });
        }else{
            NSLog(@"error when downLoad :%@",error);
        }
    
    });
    /*
     主线程串行队列由系统默认生产的,所以无法调用dispatch_resume()和
     
     dispatch_supend()来控制执行继续或中断
     
     */
}
- (void)test04 {
    /*
     耗时的操作,比如读取网络数据,IO,数据库读写等,我们会在另外一个线程中处理这些操作,然后通知主线程更新界面
     
     */
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    NSLog(@"Current task  当前线程%@",[NSThread currentThread]);

    dispatch_sync(globalQueue, ^{
    
        sleep(10.0);
        
        NSLog(@"sleep 2.0s 当前线程:%@",[NSThread currentThread]);
    });
    NSLog(@"next task 当前线程:%@",[NSThread currentThread]);
    /*
     全局并发队列同步执行任务,在主线程执行会导致页面卡顿。哦,因为没有开启新的线程去处理,始终还是在主线程操作
     
     这种写法,我从来没用过,这是什么写法.....我去。。。。。
     */
}
- (void)test05 {
    
  dispatch_queue_t globalQueue =   dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    NSLog(@"Current task  当前线程%@",[NSThread currentThread]);
   
    dispatch_async(globalQueue, ^{
    
        sleep(10.0);
        
        NSLog(@"sleep 10.0s 当前线程:%@",[NSThread currentThread]);
    
    });
    NSLog(@"next task 当前线程:%@",[NSThread currentThread]);
    
    /*
     全局并发队列异步执行任务,在主线程运行,会开启新的子线程去处理,页面不会kadun
     控制台输出:
     2017-03-30 09:25:57.384 GSDDemo[1034:37172] Current task  当前线程<NSThread: 0x7ae493a0>{number = 1, name = main}
     2017-03-30 09:25:57.385 GSDDemo[1034:37172] next task 当前线程:<NSThread: 0x7ae493a0>{number = 1, name = main}
     2017-03-30 09:26:07.459 GSDDemo[1034:37208] sleep 10.0s 当前线程:<NSThread: 0x7c150850>{number = 3, name = (null)}
     
     */
}
- (void)test06 {
    //多个全局并发队列,异步执行任务
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    NSLog(@"Current task  当前线程%@",[NSThread currentThread]);

    dispatch_async(globalQueue, ^{
        
        NSLog(@"最先加入全局并发队列 当前线程:%@",[NSThread currentThread]);

    });
    dispatch_async(globalQueue, ^{
        
        NSLog(@"次先加入全局并发队列 当前线程:%@",[NSThread currentThread]);

    });
    
    NSLog(@"next task 当前线程:%@",[NSThread currentThread]);

    /*
     异步线程的执行顺序是不确定的。几乎同步开始执行
     
     全局并发队列由系统默认生成的,所以无法调用dispatch_resume()和dispatch_suspend()来控制执行继续或中断
     控制台打印如下:
     2017-03-30 09:32:13.148 GSDDemo[1074:41000] Current task  当前线程<NSThread: 0x7ae17820>{number = 1, name = main}
     2017-03-30 09:32:13.150 GSDDemo[1074:41034] 次先加入全局并发队列 当前线程:<NSThread: 0x7ae2fc80>{number = 4, name = (null)}
     2017-03-30 09:32:13.150 GSDDemo[1074:41033] 最先加入全局并发队列 当前线程:<NSThread: 0x7b920100>{number = 3, name = (null)}
     2017-03-30 09:32:13.150 GSDDemo[1074:41000] next task 当前线程:<NSThread: 0x7ae17820>{number = 1, name = main}
     
     
     */
}
#pragma mark---自定义队列
- (void)test07 {
    //获取自定义串行队列
    dispatch_queue_t serialQueue =  dispatch_queue_create("com.dullgrass.serialQueue", DISPATCH_QUEUE_SERIAL);
    NSLog(@"%s",dispatch_queue_get_label(serialQueue));
    
    /*
     控制台输出如下:
     
     2017-03-30 09:38:27.626 GSDDemo[1121:43951] com.dullgrass.serialQueue

     */
    /*
     dispatch_queue_create(<#const char * _Nullable label#>, dispatch_queue_attr_t  _Nullable attr)
     函数中第一个参数是给这个queue起得标识,这个标识在调试的可以看到是哪个队列在执行,或者在crash日志中,也能做为提示。第二个是需要创建的队列类型,是串行的还是并发的。
     
     */
}
#pragma mark---自定义串行队列同步执行任务
- (void)test08 {
    
    dispatch_queue_t serialQueue = dispatch_queue_create("com.dullgrass.serialQueue", DISPATCH_QUEUE_SERIAL);
    NSLog(@"Current task  当前线程%@",[NSThread currentThread]);
    /*
     同步操作 没有开启新的线程,那么我用同步线程做什么??
     
     */
    dispatch_sync(serialQueue, ^{
      NSLog(@"最先加入自定义的串行队列  当前线程%@",[NSThread currentThread]);
        sleep(10);
    });
    
    dispatch_sync(serialQueue, ^{
        
        NSLog(@"次先加入自定义的串行队列  当前线程%@",[NSThread currentThread]);

    });
    
    NSLog(@"next task 当前线程%@",[NSThread currentThread]);
    /*控制台日志:
     2017-03-30 09:46:35.191 GSDDemo[1158:48321] Current task  当前线程<NSThread: 0x79656bf0>{number = 1, name = main}
     2017-03-30 09:46:35.191 GSDDemo[1158:48321] 最先加入自定义的串行队列  当前线程<NSThread: 0x79656bf0>{number = 1, name = main}
     2017-03-30 09:46:45.266 GSDDemo[1158:48321] 次先加入自定义的串行队列  当前线程<NSThread: 0x79656bf0>{number = 1, name = main}
     2017-03-30 09:46:45.266 GSDDemo[1158:48321] next task 当前线程<NSThread: 0x79656bf0>{number = 1, name = main}

     */
    
}

#pragma mark---自定义串行队列同步执行任务,产生死锁
- (void)test09{
    
    dispatch_queue_t serialQueue  =dispatch_queue_create("com.dullgrass.SerialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(serialQueue, ^{
    NSLog(@"会执行的代码 %@",[NSThread currentThread]);
        
        //嵌套同步执行的串行队列卡死在这里
        dispatch_sync(serialQueue, ^{
            NSLog(@"不会执行的代码 %@",[NSThread currentThread]);

        });
    });
    /*
     注意不要嵌套使用同步执行的串行队列
     
     */
}
#pragma mark---自定义并发队列
- (void)test10{
    dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.github.housenkui", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"current task :当前线程%@",[NSThread currentThread]);
    dispatch_sync(conCurrentQueue, ^{
        NSLog(@"先加入队列 :当前线程%@",[NSThread currentThread]);
        
    });
    dispatch_sync(conCurrentQueue, ^{
        NSLog(@"后加入队列 :当前线程%@",[NSThread currentThread]);
        
    });
    NSLog(@"next task :当前线程%@",[NSThread currentThread]);
    /*
     控制台日志:
     
     2017-03-30 10:04:58.507 GSDDemo[1304:59257] current task :当前线程<NSThread: 0x7d035800>{number = 1, name = main}
     2017-03-30 10:04:58.508 GSDDemo[1304:59257] 先加入队列 :当前线程<NSThread: 0x7d035800>{number = 1, name = main}
     2017-03-30 10:04:58.509 GSDDemo[1304:59257] 后加入队列 :当前线程<NSThread: 0x7d035800>{number = 1, name = main}
     2017-03-30 10:04:58.509 GSDDemo[1304:59257] next task :当前线程<NSThread: 0x7d035800>{number = 1, name = main}
     
     */


}
- (void)test11{
    dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.githum", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"current task :当前线程%@",[NSThread currentThread]);

    dispatch_sync(conCurrentQueue, ^{
    
        NSLog(@"先加入队列 :当前线程%@",[NSThread currentThread]);

        dispatch_sync(conCurrentQueue, ^{
            
            NSLog(@"后加入队列 :当前线程%@",[NSThread currentThread]);

        });
    });
    NSLog(@"next task :当前线程%@",[NSThread currentThread]);

    /*
     控制台输出:
     2017-03-30 10:07:54.093 GSDDemo[1326:61314] current task :当前线程<NSThread: 0x7d247130>{number = 1, name = main}
     2017-03-30 10:07:54.094 GSDDemo[1326:61314] 先加入队列 :当前线程<NSThread: 0x7d247130>{number = 1, name = main}
     2017-03-30 10:07:54.094 GSDDemo[1326:61314] 后加入队列 :当前线程<NSThread: 0x7d247130>{number = 1, name = main}
     2017-03-30 10:07:54.094 GSDDemo[1326:61314] next task :当前线程<NSThread: 0x7d247130>{number = 1, name = main}
     */
    /*
     自定义并发队列嵌套执行同步任务   不会产生死锁,程序正常运行
     */
}
- (void)test12{
    
    dispatch_queue_t conCurrentQueue  = dispatch_queue_create("com.github.housenkui", DISPATCH_QUEUE_CONCURRENT);
    NSLog(@"current task :当前线程%@",[NSThread currentThread]);

    dispatch_async(conCurrentQueue, ^{
        
        NSLog(@"先加入队列 :当前线程%@",[NSThread currentThread]);

    });
    dispatch_async(conCurrentQueue, ^{
        
        NSLog(@"后加入队列 :当前线程%@",[NSThread currentThread]);
        
    });
    NSLog(@"next task :当前线程%@",[NSThread currentThread]);

    /*
     控制台输出:
     2017-03-30 10:12:36.946 GSDDemo[1365:64255] current task :当前线程<NSThread: 0x7bf33580>{number = 1, name = main}
     2017-03-30 10:12:36.947 GSDDemo[1365:64255] next task :当前线程<NSThread: 0x7bf33580>{number = 1, name = main}
     2017-03-30 10:12:36.947 GSDDemo[1365:64294] 先加入队列 :当前线程<NSThread: 0x7d949b40>{number = 3, name = (null)}
     2017-03-30 10:12:36.947 GSDDemo[1365:64293] 后加入队列 :当前线程<NSThread: 0x7d9499f0>{number = 4, name = (null)}
     
     */
    /*
     
     异步执行任务,开启新的子线程,不影响当前线程任务的执行,
     并发队列中的任务,输出顺序不确定
     */
}
#pragma mark---队列组
/*
 当遇到需要执行多个线程并发执行,然后等多个线程结束之后,再汇总执行结果时,可以用group queue
 
 1.使用场景:同时下载多个图片,所有图片下载完之后去,更新UI(回到主线程)或者去处理其他任务
 (可以是其他线程队列)
 
 2.原理:使用函数dispatch_group_create 创建dispatch group,然后使用函数dispatch_group_async来将要执行的block任务提交到一个dispatch queue.同时将他们添加到一个组,等要执行的block任务全部执行完成之后,使用dispatch_group_notify 函数接收完成时的消息。
 
 */
- (void)test13{
    dispatch_queue_t conCurrentGlobalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    
    dispatch_group_t groupQueue = dispatch_group_create();
    
    NSLog(@"current task 当前线程:%@",[NSThread  currentThread]);
    dispatch_group_async(groupQueue, conCurrentGlobalQueue, ^{
    
        NSLog(@"并发执行 1 当前线程:%@",[NSThread currentThread]);
    
    });
    dispatch_group_async(groupQueue, conCurrentGlobalQueue, ^{
    
        NSLog(@"并发执行2 当前线程:%@",[NSThread currentThread]);
    });
    
    dispatch_group_notify(groupQueue, mainQueue, ^{
        
        NSLog(@"groupQueue中的任务都执行完,回到主线程更新UI,当前线程:%@",[NSThread currentThread]);

    
    });
    NSLog(@"next task 当前线程:%@",[NSThread currentThread]);
    
    /*控制台日志:
     
     2017-03-30 10:31:58.041 GSDDemo[1469:73285] current task 当前线程:<NSThread: 0x7d1623e0>{number = 1, name = main}
     2017-03-30 10:31:58.041 GSDDemo[1469:73345] 并发执行 1 当前线程:<NSThread: 0x7b761330>{number = 3, name = (null)}
     2017-03-30 10:31:58.041 GSDDemo[1469:73347] 并发执行2 当前线程:<NSThread: 0x7d1657d0>{number = 4, name = (null)}
     2017-03-30 10:31:58.041 GSDDemo[1469:73285] next task 当前线程:<NSThread: 0x7d1623e0>{number = 1, name = main}
     2017-03-30 10:31:58.052 GSDDemo[1469:73285] groupQueue中的任务都执行完,回到主线程更新UI,当前线程:<NSThread: 0x7d1623e0>{number = 1, name = main}
     */
}
#pragma mark---在当期线程阻塞的同步等待dispatch_group_wait()

- (void)test14{
   dispatch_group_t groupQueue  =  dispatch_group_create();
    
    dispatch_time_t delayTime  = dispatch_time(DISPATCH_TIME_NOW, 10*NSEC_PER_SEC);
    dispatch_queue_t conCurrentGlobalQueue  =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    NSLog(@"current task  当前线程:%@",[NSThread currentThread]);
    
    dispatch_group_async(groupQueue, conCurrentGlobalQueue, ^{
    
        //isExecuteOver这个值是49  ???
//FIXME:???为甚?
        long isExecuteOver  = dispatch_group_wait(groupQueue, delayTime);
        
        if (isExecuteOver) {
            NSLog(@"wait over当前线程:%@",[NSThread currentThread]);
        }
        else{
            
            NSLog(@"not over当前线程:%@",[NSThread currentThread]);
        }
        NSLog(@"并行任务1当前线程:%@",[NSThread currentThread]);
    
    });
    dispatch_group_async(groupQueue, conCurrentGlobalQueue, ^{
     
       NSLog(@"并行任务2当前线程:%@",[NSThread currentThread]);
    });
    /*
     控制台日志:
     
     2017-03-30 10:40:21.103 GSDDemo[1504:76995] current task  当前线程:<NSThread: 0x7c14fe60>{number = 1, name = main}
     2017-03-30 10:40:21.104 GSDDemo[1504:77028] 并行任务2当前线程:<NSThread: 0x79f6a7f0>{number = 3, name = (null)}
     2017-03-30 10:40:31.161 GSDDemo[1504:77026] wait over当前线程:<NSThread: 0x7c155ce0>{number = 4, name = (null)}
     2017-03-30 10:40:31.162 GSDDemo[1504:77026] 并行任务1当前线程:<NSThread: 0x7c155ce0>{number = 4, name = (null)}
     */
    
    /*
     dispatch_time(dispatch_time_t when,int64_t delta);
     
     参数注释:
     第一个参数一般是:DISPATCH_TIME_NOW,表示从现在开始
     
     第二个参数是延时的具体时间:
     
     延时1秒可以写成如下2种:
     NSEC_PER_SEC----每秒有多少纳秒
     dispatch_time(DISPATCH_TIME_NOW, 1*NSEC_PER_SEC);
     USEC_PER_SEC----每秒有多少毫秒(注意是指在纳秒的基础上)
     dispatch_time(DISPATCH_TIME_NOW, 1000*USEC_PER_SEC); //SEC---毫秒
    
     
     */
    
}
#pragma mark----dispatch_after

- (void)test15{
    dispatch_time_t delayTime3 = dispatch_time(DISPATCH_TIME_NOW, 3*NSEC_PER_SEC);
    
    dispatch_time_t delayTime2 = dispatch_time(DISPATCH_TIME_NOW, 2*NSEC_PER_SEC);
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    NSLog(@"curren task");

    dispatch_after(delayTime3, mainQueue, ^{
    
        NSLog(@"第3秒之后 添加到队列");
    });
    dispatch_after(delayTime2, mainQueue, ^{
    
        NSLog(@"第2秒之后 添加到队列");

    });
    NSLog(@"next task");
    /*
     控制台打印:
     
     2017-03-30 10:52:59.913 GSDDemo[1616:84429] curren task
     2017-03-30 10:52:59.914 GSDDemo[1616:84429] next task
     2017-03-30 10:53:02.113 GSDDemo[1616:84429] 第2秒之后 添加到队列
     2017-03-30 10:53:03.171 GSDDemo[1616:84429] 第3秒之后 添加到队列
     
     dispatch_after 只是延时提交block ,并不是延迟后执行,并不能做到精确控制。
     */
    
}
#pragma mark----dispatch_apply
/*
 dispatch_apply函数的功能:把一项任务提交到队列中多次执行
 */

- (void)test16{
    
    dispatch_queue_t globalQueue  = dispatch_get_global_queue(0, 0);
    
    NSLog(@"current task     当前线程%@",[NSThread currentThread]);
    
    dispatch_async(globalQueue, ^{
        dispatch_queue_t applyQueue = dispatch_get_global_queue(0, 0);
        
        /*
         第一个参数:3----block的执行次数
         第二个参数:applyQueue ----block任务提交到的队列
         第三个参数:block----需要重复执行的任务
         */
        dispatch_apply(3, applyQueue, ^(size_t index){
           
            NSLog(@"current index %@      当前线程%@",@(index),[NSThread currentThread]);
            sleep(1);
        });
        NSLog(@"dispatch_apply 执行完成   当前线程%@",[NSThread currentThread]);
        
      dispatch_queue_t mainQueue  =   dispatch_get_main_queue();
        
        dispatch_async(mainQueue, ^{
        
        NSLog(@"回到主线程更新UI   当前线程%@",[NSThread currentThread]);
        
        });
    
    });
    NSLog(@"next task %@",[NSThread currentThread]);
    /*
     控制台:
     2017-03-30 11:13:02.196 GSDDemo[1683:92762] current task     当前线程<NSThread: 0x7c110b50>{number = 1, name = main}
     2017-03-30 11:13:02.197 GSDDemo[1683:92801] current index 1      当前线程<NSThread: 0x7a716720>{number = 3, name = (null)}
     2017-03-30 11:13:02.197 GSDDemo[1683:92798] current index 0      当前线程<NSThread: 0x7a627b10>{number = 4, name = (null)}
     2017-03-30 11:13:02.197 GSDDemo[1683:92799] current index 2      当前线程<NSThread: 0x7a62b5e0>{number = 5, name = (null)}
     2017-03-30 11:13:02.197 GSDDemo[1683:92762] next task <NSThread: 0x7c110b50>{number = 1, name = main}
     2017-03-30 11:13:03.198 GSDDemo[1683:92798] dispatch_apply 执行完成   当前线程<NSThread: 0x7a627b10>{number = 4, name = (null)}
     2017-03-30 11:13:03.198 GSDDemo[1683:92762] 回到主线程更新UI   当前线程<NSThread: 0x7c110b50>{number = 1, name = main}

     
     嵌套使用dispatch_apply会导致死锁。

     */
}
#pragma mark----dispatch_barrier_async 挡板

/*
 功能:是在并行队列中,等待dispatch_barrier_asnc之前加入的队列全部执行完成之后,再执行dispatch_barrier_async的任务,执行完城之后,再去执行在dispatch_barrier_async之后加入到队列中的任务 (这些任务是并发执行的,日志输出的顺序不确定)
 */
- (void)test17{
   __block NSData *dataImage;
    dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.github.housenkui", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(conCurrentQueue, ^{
    
    NSLog(@"dispatch 1当前线程%@",[NSThread currentThread]);
        
        NSString *loadstring  = @"http://pic68.nipic.com/file/20150526/21011915_230134210000_2.jpg";
        
        NSURL *url  =[NSURL URLWithString:loadstring];
        
        dataImage = [NSData dataWithContentsOfURL:url];
        
        //让子线程休眠,很少用
        sleep(5);
        
        NSLog(@"dispatch 1 sleep 当前线程%@",[NSThread currentThread]);

        
    });
    
    dispatch_async(conCurrentQueue, ^{
    
    NSLog(@"dispatch 2当前线程%@",[NSThread currentThread]);
    
    });
    
    dispatch_barrier_async(conCurrentQueue, ^{
    
    NSLog(@"dispatch  barrier 当前线程%@",[NSThread currentThread]);
        
        if(dataImage ){
            
            NSLog(@"下载完成");
         }
        else
         {
            NSLog(@"没有下载完成");
         }
    });
    dispatch_async(conCurrentQueue, ^{
    
        NSLog(@"dispatch 3当前线程%@",[NSThread currentThread]);
    });
    dispatch_async(conCurrentQueue, ^{
        
        NSLog(@"dispatch 4当前线程%@",[NSThread currentThread]);
    });

    dispatch_async(conCurrentQueue, ^{
        
        NSLog(@"dispatch 5当前线程%@",[NSThread currentThread]);
    });

    /*
     控制台日志:
     2017-03-30 11:32:23.253 GSDDemo[1855:104995] dispatch 2当前线程<NSThread: 0x7c075f70>{number = 4, name = (null)}
     2017-03-30 11:32:23.253 GSDDemo[1855:104992] dispatch 1当前线程<NSThread: 0x7c16f580>{number = 3, name = (null)}
     2017-03-30 11:32:28.680 GSDDemo[1855:104992] dispatch 1 sleep 当前线程<NSThread: 0x7c16f580>{number = 3, name = (null)}
     2017-03-30 11:32:28.681 GSDDemo[1855:104992] dispatch  barrier 当前线程<NSThread: 0x7c16f580>{number = 3, name = (null)}
     2017-03-30 11:32:28.681 GSDDemo[1855:104992] 下载完成
     2017-03-30 11:32:28.682 GSDDemo[1855:104992] dispatch 3当前线程<NSThread: 0x7c16f580>{number = 3, name = (null)}
     2017-03-30 11:32:28.682 GSDDemo[1855:104993] dispatch 4当前线程<NSThread: 0x7c264160>{number = 6, name = (null)}
     2017-03-30 11:32:28.682 GSDDemo[1855:105041] dispatch 5当前线程<NSThread: 0x7c277990>{number = 7, name = (null)}
     
     */
}
- (void)viewDidLoad {
    [super viewDidLoad];
    
   
    [self test17];
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    // Do any additional setup after loading the view, typically from a nib.
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

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

推荐阅读更多精彩内容