GCD和NSOperation 的概念,用法及之间的区别

Posted 雷坤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GCD和NSOperation 的概念,用法及之间的区别相关的知识,希望对你有一定的参考价值。

 

CGD与NSOperation的区别

 

gcd是基于c的底层api,NSOperation属于object-c类。
相对于gcd:
1,NSOperation拥有更多的函数可用,具体查看api。
2,在NSOperationQueue中,可以建立各个NSOperation之间的依赖关系。
3,有kvo,可以监测operation是否正在执行(isExecuted)、是否结束(isFinished),是否取消(isCanceld)。
4,NSOperationQueue可以方便的管理并发、NSOperation之间的优先级。
gcd主要与block结合使用。

======================================================

 

#pragma mark - 使用GCD去创建一个串行队列
    // 第一种: 系统提供的创建串行队列方法
   // dispatch_queue_t queue = dispatch_get_main_queue();// 在真正的开发中如果需要创建串行队列,比较习惯用这种
    
   //  第二种: 自己去创建
    // 参数1: 系统提供的一个宏
    // 参数2: 系统的保留字段
    // 两个参数的位置没有严格的限定,只要写两个参数即可
   // dispatch_queue_t queue = dispatch_queue_create(DISPATCH_QUEUE_SERIAL, 0);serial 串行
    
#pragma mark -- 使用GCD去创建并行队列
    // 第一种方式: 系统的方式
    // 参数1: 优先级 (有四个,没有明显的区别)
    // 参数2: 系统保留字
  //  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    
    // 第二种方式: 自己创建的
    // 参数1: 表示队列的名字
    // 参数2: 系统提供的宏
//    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);//concurrent 并发
//    
//    dispatch_async(queue, ^{
//        NSLog(@"current1 = %@, mainThread = %@", [NSThread currentThread], [NSThread mainThread]);
//    });
   
#pragma mark - 几秒之后去做每一件事
    
    // 参数1:
    // 参数2:
    // 参数3:
    
   // dispatch_time
    // 参数1: 什么时候
    // 参数2:
    
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//        NSLog(@"3.0秒时候");
//    });
//    
#pragma mark - 重复向一个队列中添加多个任务
//    dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);// 并行
//    // 参数1; 设置的个数
//    // 参数2: 队列
//    // 参数3: block后加参数名 (index)
//    
//    dispatch_apply(100, queue, ^(size_t index) {
//        NSLog(@"%ld", index);
//        
//    });
//    
    
#pragma mark - 分组
    
//    // 创建一个分组
//    dispatch_group_t group = dispatch_group_create();
//    
//    // 创建一个并行队列
//    dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);
//    
//    // 创建任务1:
//    dispatch_group_async(group, queue, ^{
//        NSLog(@"我是任务1");
//        
//        
//        
//    });
//    
//  
//    // 创建任务2
//    dispatch_group_async(group, queue, ^{
//        NSLog(@"我是任务2");
//    });
//    
//    // 用于监听所有任务的执行情况 [所以此功能代码必须放在所有任务之后进行书写]
//    dispatch_group_notify(group, queue, ^{
//        NSLog(@"我是在所有任务之后执行的");
//    });
//    
#pragma mark - 并发中的串行 (披着羊皮的狼)
    // DISPATCH_QUEUE_SERIAL 串行: 特点: 任务顺序执行
    // DISPATCH_QUEUE_CONCURRENT 并行 特点: 无序的
    
    // 创建队列 (串行)
    dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_SERIAL);
    // 添加任务
    dispatch_async(queue, ^{
        NSLog(@"任务1");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"任务2");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"任务3");
    });
    dispatch_async(queue, ^{
        NSLog(@"任务4");
    });
    dispatch_async(queue, ^{
        NSLog(@"任务5");
    });
    
    [self loadData];
    
}

- (void)loadData
{
    // 创建URL
    NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
    // 创建session
    NSURLSession *session = [NSURLSession sharedSession];
    
    // 创建NSRULSessionTask
    NSURLSessionTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil) {
            
            // 处理数据
            
            // 回到主线程刷新UI
            dispatch_async(dispatch_get_main_queue(), ^{
            });
        }
    }];
}
===========================================================

使用GCD 开辟子线程请求数据 回到主线程刷新数据(展示图片)

 self.imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.imageView.backgroundColor = [UIColor redColor];
    [self.view addSubview:self.imageView];
    
    // 自己创建的
//    dispatch_async(dispatch_queue_create(@"myQueue", DISPATCH_QUEUE_CONCURRENT), <#^(void)block#>)
    
    
    // 系统方式
    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    
    dispatch_async(queue, ^{
       
        // ======处理数据库=======
        
        // 创建URL===
        NSURL *url = [NSURL URLWithString:@"http://img2.3lian.com/2014/f6/127/d/39.jpg"];
        // 转换成数据
        NSData *data = [[NSData alloc] initWithContentsOfURL:url];
        // 初始化
        UIImage *image = [[UIImage alloc] initWithData:data];
        if (data != nil) {
            dispatch_async(dispatch_get_main_queue(), ^{
                // =====刷新界面======
                self.imageView.image = image;
            });
        }
        NSLog(@"current1 = %@, mainThread = %@", [NSThread currentThread], [NSThread mainThread]);
    });

=========================================================================-

NSOperationQueue的用法

(void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    // NSOperation不能直接进行多线程的创建,需要借助 :NSOperationQueue
    
    // 使用NSOperation的第一个子类去创建子线程 :NSInvocationOperation
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test) object:nil];
    
    // 在单独使用子NSOperation的子类去创建线程的时候,一定要启动
   // [operation start];
    // 在使用NSOperation的子类去创建线程的时候,实际上线程没有真正意义上的创建
    
    // 使用NSOperation的第二个子类创建线程
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        
        NSLog(@"我是block");
        NSLog(@"======currentThread == %@", [NSThread currentThread]);
        NSLog(@"=====%@", [NSThread mainThread]);
        
    }];
    
    // 只有启动的时候才会调用block中的内容
    //[blockOperation start];
    
    // 需要把上面的两个线程,放到操作队列里
    // addOperation一旦创建的对象加入到操作对列中,就不能调用start,否则会崩溃
//    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//    [queue addOperation:operation];
//    [queue addOperation:blockOperation]; 
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 创建队列的对象
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 最大的并发数量值
    // 当值设置为1的时候,可以叫做串行: 即顺序执行
    
    // 当值设置大于1的时候,叫做并行: 多条通道同时进行各自的任务
    queue.maxConcurrentOperationCount = 2;
    
    for (int i = 0; i < 10; i++) {
        NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
            
            NSLog(@"++++++currentThread == %@", [NSThread currentThread]);
            NSLog(@"++++++mainThread == %@", [NSThread mainThread]);
            NSLog(@"===%d", i);
            
        }];
        [queue addOperation:blockOperation];
    }
}

- (void)test
{
    NSLog(@"??????");
    NSLog(@"currentThread == %@", [NSThread currentThread]);
    NSLog(@"mainThread == %@", [NSThread mainThread]);
}
=========================================================

 

以上是关于GCD和NSOperation 的概念,用法及之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发-NSOperation与GCD区别

iOS中用GCD和NSOperation多个异步操作的关联

iOS开发-NSOperation与GCD区别

多线程之pthread, NSThread, NSOperation, GCD

NSOperation

iOS多线程NSThread,NSOperation和GCD详解