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]);
}
=========================================================

时间: 2024-08-07 04:33:20

GCD和NSOperation 的概念,用法及之间的区别的相关文章

【iOS沉思录】NSThread、GCD、NSOperation多线程编程总结

OC中的多线程 OC中多线程根据封装程度可以分为三个层次:NSThread.GCD和NSOperation,另外由于OC兼容C语言,因此仍然可以使用C语言的POSIX接口来实现多线程,只需引入相应的头文件:#include <pthread.h>. NSThread NSThread是封装程度最小最轻量级的,使用更灵活,但要手动管理线程的生命周期.线程同步和线程加锁等,开销较大: NSThread的基本使用比较简单,可以动态创建初始化NSThread对象,对其进行设置然后启动:也可以通过NST

iOS多线程——GCD与NSOperation总结

很长时间以来,我个人(可能还有很多同学),对多线程编程都存在一些误解.一个很明显的表现是,很多人有这样的看法: 新开一个线程,能提高速度,避免阻塞主线程 毕竟多线程嘛,几个线程一起跑任务,速度快,还不阻塞主线程,简直完美. 在某些场合,我们还见过另一个“高深”的名词——“异步”.这东西好像和多线程挺类似,经过一番百度(阅读了很多质量层次不齐的文章)之后,很多人也没能真正搞懂何为“异步”. 于是,带着对“多线程”和“异步”的懵懂,很多人又开开心心踏上了多线程编程之旅,比如文章待会儿会提到的GCD.

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

在iOS实际开发中,我们可能会遇到下面的场景:有以下四个操作A,B,C,D.要求A,B,C在子线程中执行,当A,B,C执行完毕之后回到主线程执行操作D,ABC之间可能会有相互依赖的关系,我们可以通过GCD和NSOperation都可以实现这样的需求. 1.GCD // 用GCD - (void)useGCD { // 1.1可以创建一个全局并发队列,A,B,C操作会在子线程中并发执行,ABC不存在先后执行顺序 // dispatch_queue_t quque=dispatch_get_glob

多线程——NSThread、GCD、NSOperation

1.前言: 一个应用程序就是一个进程,一个进程至少包含一个线程,程序启动会自动创建一个主线程,负责UI界面的现实和控件事件的监控.多线程可以更充分的利用系统CPU资源,一定程度上提升程序的性能.1个进程可以开启多条线程,每条线程可以并行(同时)执行不同的任务.在一个线程内可以包含多个事物(要干的活),在线程内依据先进先出的特性串行执行…… 2.NSThread - (void)viewDidLoad { [super viewDidLoad]; NSLog(@"main thread is %@

数组去重,call、apply、bind之间的区别,this用法总结

一.数组去重,直接写到Array原型链上. 1 //该方法只能去除相同的数字 不会去判断24和'24'是不同的 所有数字和字符串数字是相同是重复的 2 Array.prototype.redup=function(){ 3 var obj={}; 4 for(var i=0;i<this.length;i++){ 5 var val=this[i]; 6 if(obj[val]==this[i]){ //如果发现重复的 7 this[i]=this[this.length-1]; //那就把最后

JDBC中PreparedStatement接口提供的execute、executeQuery和executeUpdate之间的区别及用法

JDBC中PreparedStatement接口提供的execute.executeQuery和executeUpdate之间的区别及用法 (2012-08-27 09:36:18) 转载▼ 标签: statement execute executequery executeupdate 杂谈 分类: DataBase区 PreparedStatement接口提供了三种执行 SQL 语句的方法:executeQuery.executeUpdate 和 execute.使用哪一个方法由 SQL 语

css中字体单位px,pt,em ,rem,百分比之间的区别和用法

css中字体单位px,pt,em ,rem,百分比之间的区别和用法 px 即像素,一般国内网站使用较多,默认大小是16px; pt 印刷行业常用单位 em  相对单位,相对父元素属性的单位 ,一般用于移动端布局 rem  结合相对定位和绝对定位的优势,相对根元素html,想要修改字体大小,只要修改html的大小就可以了 转换公式: pt=px乘以3/4 倍数em=倍数x16px 注意:1em=16px.那么12px=0.75em,10px=0.625em.   1.em的用法 在代码重写的过程中

IOS中的多线程实现:NSThread、GCD和NSOperation

1.NSThread 先创建,后启动 NSThread *thread = [NSThread allc] initWithTarget:self selector:@selector(run) object:nil]; [thread start]; 直接启动 2.GCD 3.NSOperation

外发外协外包三者之间的区别与联系

1.应当贯彻顾客为中心原则,通过建立体系来控制过程,确保产品质量.不要化精力在符合标准要求上.如果您 的目标.产品的要求不切合顾客要求的话,就是符合了ISO 9001标准要求,不能满足顾客要求的,符合顾客要求了,顾客满意了,不注意质量成本,经济效益,也就不一定能赚到钱的. 2.7.4条采购要求是,如果您从质量管理体系外得到各种影响产品要求符合性的资源(过程也作为一种资源)的话,就必须对这些产品或者活动(也就是过程) 加以控制的."采购"英文是purchasing,"外包过程&