NSOperation多线程的使用与理解

1. 是一个抽象的类,不能直接使用.只有定义,没有实现.

2. 作为父类,约束子类的一些共有的属性和方法

3. 两个子类:

    NSInvocationOperation

    NSBlockOperation

4. 队列 : NSOperationQueue,默认是并发队列;

5. OP的核心 : 将操作添加到队列中

     两种写法:1---这种写法不能获取操作对象

        [self.queue addOperationWithBlock:^{

            // 查看当前的线程

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

        }];


         方法2------------

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

    

    // 子类NSBlockOperation创建操作对象 : 默认是异步的

    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{

        // 查看当前的线程

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

    }];

    

    // 将操作添加到队列

    [queue addOperation:op];


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

    //子类 NSInvocationOperation创建操作对象

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

    

    // 创建队列

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

    

    // 将操作对象添加到队列

    [queue addOperation:op];




6. GCD的核心 : 将任务添加到队列

7.NSOperationQueue的操作默认是异步的,会开启新线程,

8. 回到主线程更新UI

        [[NSOperationQueue mainQueue] addOperationWithBlock:^{

            // 查看当前的线程

            NSLog(@"更新UI...%@",[NSThread currentThread]);

        }];


9.   设置队列的最大并发数

  间接控制了线程的数量,最少2个线程.但是不会开太多

       

[[NSOperationQueue allocinit].maxConcurrentOperationCount = 2;

   或者     

[[[NSOperationQueue allocinit] setMaxConcurrentOperationCount:2];


10.暂停队列

// 表示队列"暂时"不能调度操作执行

    // 正在执行的操作不能被暂停

    // operationCount : 表示队列中的操作个数

    // 计算的是队列中正在执行和,没有执行的操作的总个数.执行完成的操作不会计算在内

    // 注意 : 不要先暂停队列,一旦先暂停了队列,那么队列是不会去调度操作执行的

    self.queue.suspended = YES;


11.取消队列

    // 取消队列中的全部操作  :正在执行的操作是无法取消的

    // 如果想取消需要自定义NSOperation

    // 类似于字典中移除全部的对象

    // 调用这个方法,表示队列向队列中的所有操作发送cancel消息

    

    // 这个方法有延迟时间

    [self.queue cancelAllOperations];


12.设置操做的优先级 : 优先级最高

    // 同样的不能够决定操作的执行的先后顺序.决定这个操作有更多的机会被调度执行

    op1.qualityOfService = NSQualityOfServiceUserInteractive;


13.操作间的依赖

    // 创建登陆操作

    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{

        // 查看当前的线程

        NSLog(@"登陆 %@",[NSThread currentThread]);

    }];

//    [self.queue addOperation:op1];

    

    // 创建付费操作

    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{

        // 查看当前的线程

        NSLog(@"付费 %@",[NSThread currentThread]);

    }];

    

    // 创建下载操作

    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{

        // 查看当前的线程

        NSLog(@"下载 %@",[NSThread currentThread]);

    }];

    

    // 创建通知用户的操作

    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{

        // 查看当前的线程

        NSLog(@"通知用户 %@",[NSThread currentThread]);

    }];

    

    // 建立依赖关系

    // 付费依赖登陆

    [op2 addDependency:op1];

    // 下载依赖付费

    [op3 addDependency:op2];

    // 通知用户依赖下载

    [op4 addDependency:op3];

    

    // 登陆是不需要依赖任何操作的

    // 如果登陆依赖通知用户,就是循环依赖,此时,队列是不会调度任务执行的

    // 注意 : 绝对不能做

//    [op1 addDependency:op4];

    

    // 统一的将操作添加到队列

    // waitUntilFinished : 表示是否等待前面的任务执行结束,在执行后面的任务

    [self.queue addOperations:@[op1,op2,op3] waitUntilFinished:NO];

    

    // 将通知用户的操作添加到主队列中

    // 操作间的依赖是可以跨队列建立的

    [[NSOperationQueue mainQueue] addOperation:op4];

    

    // 注意 : 千万不要在添加到队列之后,再建立依赖关系,因为队列已经在调度任务执行了



你可能感兴趣的:(NSOperation多线程的使用与理解)