GCD,NSThread,NSOperation

为了方便看, 定义三个button:


//  ViewController.h

#import

@interface ViewController : UIViewController

@property (nonatomic, retain) UIImageView *MyimageView;


@end



//  ViewController.m

#import "ViewController.h"


@interface ViewController ()


@end


@implementation ViewController

1.定义三个按钮

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.


    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];

    button1.frame = CGRectMake(60, 40, 200, 40);

    [button1 setTitle:@"NSThread" forState:UIControlStateNormal];

    button1.backgroundColor = [UIColor orangeColor];

    [self.view addSubview:button1];

    [button1 addTarget:self action:@selector(button1Action:) forControlEvents:UIControlEventTouchUpInside];

    

    UIButton *button2 = [UIButton buttonWithType:UIButtonTypeCustom];

    button2.frame = CGRectMake(60, 100, 200, 40);

    [button2 setTitle:@"NSOperation" forState:UIControlStateNormal];

    button2.backgroundColor = [UIColor greenColor];

    [self.view addSubview:button2];

    [button2 addTarget:self action:@selector(button2Action:) forControlEvents:UIControlEventTouchUpInside];

    

    UIButton *button3 = [UIButton buttonWithType:UIButtonTypeCustom];

    button3.frame = CGRectMake(60, 160, 200, 40);

    [button3 setTitle:@"GCD" forState:UIControlStateNormal];

    button3.backgroundColor = [UIColor cyanColor];

    [self.view addSubview:button3];

    [button3 addTarget:self action:@selector(button3Action:) forControlEvents:UIControlEventTouchUpInside];



    

    self.MyimageView = [[UIImageView alloc] initWithFrame:CGRectMake(60, 300, 200, 200)];

    [self.view addSubview:self.MyimageView];

    self.MyimageView.backgroundColor = [UIColor lightGrayColor];

    

}



2.,下载图片的方法

- (void)DownLoadImage

{

    NSString *urlStr = @"http://amuse.nen.com.cn/imagelist/11/21/9as70n3ir61b.jpg";

    NSURL *url = [NSURL URLWithString:urlStr];

    NSData *data = [NSData dataWithContentsOfURL:url];

    UIImage *image = [UIImage imageWithData:data];

}


#pragma mark -- 多线程之 NSThread

- (void)button1Action:(UIButton *)button1

{

    // NSLog(@"aa");

    

    // 自定义多线程

    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(action:) object:@"大水杯"];

    // 开启多线程

    [thread start];

    

    // 使用系统的

    [NSThread detachNewThreadSelector:@selector(DownLoadImage) toTarget:self withObject:nil];

    

    NSLog(@"当前线程为 %@ 是否为主线程 %d", [NSThread currentThread], [NSThread isMainThread]);

}


实现两个方法, 看在 NSOperation下的运行顺序
方法1

- (void)action1

{

    NSLog(@"action1");

}


方法2

- (void)action:(NSString *)str

{

    NSLog(@"当前线程为 %@ 是否为主线程 %d", [NSThread currentThread], [NSThread isMainThread]);

    NSLog(@"str = %@", str);

//    for (int i = 0; i < 1000000; i++) {

//        NSLog(@"i = %d", i);

//    }

}



#pragma mark -- 多线程之 NSOperation

- (void)button2Action:(UIButton *)button2

{

   // NSLog(@"bb");

    // NSOperation 是抽象类 我是用它提供的两个子类

    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(action:) object:@"大水表"];

     NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(action1) object:nil];

    

    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{

            for (int i = 0; i < 100; i++) {

                NSLog(@"i = %d", i);

            }


        

    }];

    

    

    

    

    // 队列 用来管理队列里的一个或多个任务

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    

    // 最大允许并发执行任务的个数

    [queue setMaxConcurrentOperationCount:2];

    

    // 绑定一个任务 就是前者必须等到后者执行完才能执行

    [operation addDependency:blockOperation];

    

    // 将任务加到队列中

    [queue addOperation:operation];

    [queue addOperation:operation1];

    [queue addOperation:blockOperation];

}

CGD的使用.分为串行和并行, 为了避免之间的影响, 有一些地方注释了,可根据需要自行解开

- (void)button3Action:(UIButton *)button3

{

#pragma mark -- GCD之串行 serial

    // NSLog(@"cc");


    // 串行特点 一个一个执行, 一个执行完在执行下一个

    // 1.系统自带串行队列

    // 1.1 创建系统主队列

#warning 重点经常用到, 作用:从子线程上得到主线程

/*

    dispatch_queue_t mainQueue = dispatch_get_main_queue();

    // 1.2 执行主队列

    dispatch_async(mainQueue, ^{

        

//        NSLog(@"1 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);

//        NSLog(@"2 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);

//        NSLog(@"3 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);

    });

 */

    

#warning 重要  非常常见的写法

 /*

    dispatch_async(dispatch_get_main_queue(), ^{

        

        NSLog(@"获得主线程的大众写法");

    });

    

    */

    

    // 2.自定义串行队列

    // 2.1 创建自定义串行队列

    // 参数1. 队列标识符 一般是逆向域名

    // 参数2.队列类型

 /*   dispatch_queue_t mySerialQueue = dispatch_queue_create("com.lanou3g.GCD.Serial", DISPATCH_QUEUE_SERIAL);

  */

    // 2.2 执行队列

    /*

    dispatch_async(mySerialQueue, ^{

        NSLog(@"1 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);

        NSLog(@"2 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);

        NSLog(@"3 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);

        NSLog(@"4 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);


        

    });

    

    */

    

#pragma mark -- GCD 并行

#warning 重要 经常跟dispatch_get_main_queue 一起使用

    // 1.得到全局队列

    // 参数1.队列优先级

    // 参数2.苹果预留参数,默认给0

    /*

    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    // 2. 执行队列

    dispatch_sync(globalQueue, ^{

        

    NSLog(@"1 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);


    });

     

     dispatch_sync(globalQueue, ^{

     

     NSLog(@"2 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);

     

     });

     

     dispatch_sync(globalQueue, ^{

     

     NSLog(@"3 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);

     

     });

     */

    

    // 自定义并行队列

    // 1.创建自定义并行队列

    /*

    dispatch_queue_t myConcurrentQueue = dispatch_queue_create("com.lanou3g.GCD.ConCurrentQueue", DISPATCH_QUEUE_CONCURRENT);

    // 执行队列

    dispatch_async(myConcurrentQueue, ^{

        

        NSLog(@"1 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);

        

    });

    

    dispatch_async(myConcurrentQueue, ^{

        NSLog(@"2 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);


    });

    

    dispatch_async(myConcurrentQueue, ^{

        NSLog(@"3 = %@ %d", [NSThread currentThread], [NSThread isMainThread]);

        

    });

*/

#warning 重要

    // 练习 子线程请求图片  主线程负责刷新显示图片

    

    // 1.dispatch_get_global_queue 创建系统并行队列

    // 2.dispatch_async 执行队列

/*    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        

       // 此块中是子线程

        NSString *urlStr = @"http://amuse.nen.com.cn/imagelist/11/21/9as70n3ir61b.jpg";

        NSURL *url = [NSURL URLWithString:urlStr];

        NSData *data = [NSData dataWithContentsOfURL:url];

        UIImage *image = [UIImage imageWithData:data];

        

        // block里不要用self

        __block ViewController *vc = self;

        // 在主线程中显示图片

        

        dispatch_async(dispatch_get_main_queue(), ^{

            

            vc.MyimageView.image = image;

        });

        

    });

 */

    

#warning 重要

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        

        NSLog(@"%@ %d", [NSThread currentThread], [NSThread isMainThread]);

    });

    

    // 2.只执行一次

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

        NSLog(@"2 %@ %d", [NSThread currentThread], [NSThread isMainThread]);


        

    });

   }





你可能感兴趣的:(多线程)