iOS-多线程-NSOperation

来源:互联网 发布:软件学校 编辑:程序博客网 时间:2024/06/10 19:52

一,什么是NSOpeation
NSOperation是苹果提供给我们的一套多线程解决方案。实际上NSOperation是基于GCD更高一层的封装,但是比GCD更简单易用、代码可读性也更高。


二,NSOperation&NSOperationQueue的基本使用
1,NSOperation
NSOperation是一个抽象类,并不能封装任务,我们只有使用他的子类来封装任务.有三钟方式来封装:

  • 使用子类NSInvocationOperation
  • 使用子类NSBlockOperation 定义继承NSOperation的子类,通过实现内部相应的方法来封装任务

  • NSInvocationOperation

    //1,创建NSInvoctionOperation    NSInvocationOperation *invocation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run) object:nil];    //2,调用start开始操作    [invocation start];    //没有使用NSOperation类时,并没有开启新的线程(在主线程执行)
  • NSBlockOperation
    //创建NSBlockOperation    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"执行任务-- %@",[NSThread currentThread]);        }];   //start    [blockOperation start];    //使用NSBlockOperation,没有开启行的线程(在主线程执行)
  • NSBlockOperation的addExecutionBlock:
    //创建NSBlockOperation    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"执行任务1-- %@",[NSThread currentThread]);    }];    // 添加额外的任务(在子线程执行)    [blockOperation addExecutionBlock:^{        NSLog(@"2------%@", [NSThread currentThread]);    }];    [blockOperation addExecutionBlock:^{        NSLog(@"3------%@", [NSThread currentThread]);    }];    [blockOperation addExecutionBlock:^{        NSLog(@"4------%@", [NSThread currentThread]);    }];    [blockOperation start];   //使用NSBlockOperation的addExecutionBlock:方法,会开启线程
  • 自定义继承NSOperation的子类

.h文件

import <Foundation/Foundation.h>@interface GSOperation : NSOperation@end

.m文件

#import "GSOperation.h"@implementation GSOperation//执行需要执行的任务-(void)main{    for (int i = 0; i < 9; ++i) {        NSLog(@"执行任务--%@",[NSThread currentThread]);    }}@end

单独使用自定义子类的情况下,是在主线程执行操作,并没有开启新线程。

2,NSOperationQueue
NSOperationQueue一共有两种队列:主队列、其他队列,其他队列同时包含了串行、并发功能。

  • 主队列:
    凡是添加到主队列中的任务(NSOperation),都会放到主线程中执行
    NSOperationQueue *queue = [NSOperationQueue mainQueue];

  • 其他队列(非主队列)
    添加到这种队列中的任务(NSOperation),就会自动放到子线程中执行
    同时包含了:串行、并发功能
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

将任务加入到队列中
总共有两种方法:
1,NSOperationQueue的addOperation:方法,需要先创建任务,再将创建好的任务加入到创建好的队列中去

    // 1.创建队列    NSOperationQueue *queue = [[NSOperationQueue alloc] init];    // 2. 创建操作    // 创建NSInvocationOperation    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];    // 创建NSBlockOperation    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{        for (int i = 0; i < 2; ++i) {            NSLog(@"1-----%@", [NSThread currentThread]);        }    }];    // 3. 添加操作到队列中:addOperation:    [queue addOperation:op1]; // [op1 start]    [queue addOperation:op2]; // [op2 start]

总结:不管是NSInvocationOperation,还是NSBlockOperation,在添加到队列后都可以并发执行,

2,addOperationWithBlock:无需先创建任务,在block中添加任务,直接将任务block加入到队列中.

  // 1. 创建队列    NSOperationQueue *queue = [[NSOperationQueue alloc] init];    // 2. 添加操作到队列中:addOperationWithBlock:    [queue addOperationWithBlock:^{        for (int i = 0; i < 2; ++i) {            NSLog(@"-----%@", [NSThread currentThread]);        }    }];

总结:可以并行执行


三,控制串行执行和并行执行的关键
NSOperationQueue创建的其他队列同时具有串行、并发功能,关键操作在于maxConcurrentOperationCount:(最大并发数)这个参数中

  • 默认情况下maxConcurrentOperationCount为-1,表示不进行限制,默认为并发执行。
  • 当maxConcurrentOperationCount为1时,进行串行执行。
  • 当maxConcurrentOperationCount大于1时,进行并发执行,当然这个值不应超过系统限制,即使自己设置一个很大的值,系统也会自动调整。
    // 创建队列    NSOperationQueue *queue = [[NSOperationQueue alloc] init];    // 设置最大并发操作数    //    queue.maxConcurrentOperationCount = 2;    queue.maxConcurrentOperationCount = 1; // 就变成了串行队列    // 添加操作    [queue addOperationWithBlock:^{        NSLog(@"1-----%@", [NSThread currentThread]);        [NSThread sleepForTimeInterval:0.01];    }];    [queue addOperationWithBlock:^{        NSLog(@"2-----%@", [NSThread currentThread]);        [NSThread sleepForTimeInterval:0.01];    }];    [queue addOperationWithBlock:^{        NSLog(@"3-----%@", [NSThread currentThread]);        [NSThread sleepForTimeInterval:0.01];    }];    [queue addOperationWithBlock:^{        NSLog(@"4-----%@", [NSThread currentThread]);        [NSThread sleepForTimeInterval:0.01];    }];    [queue addOperationWithBlock:^{        NSLog(@"5-----%@", [NSThread currentThread]);        [NSThread sleepForTimeInterval:0.01];    }];    [queue addOperationWithBlock:^{        NSLog(@"6-----%@", [NSThread currentThread]);        [NSThread sleepForTimeInterval:0.01];    }];

总结:当最大并发数为1时,任务是按顺序串行执行的。当最大并发数为2时,任务是并发执行的。而且开启线程数量是由系统决定的,不需要我们来管理


四,操作依赖
A、B两个操作,其中A执行完操作,B才能执行操作,那么就需要让B依赖于A。具体如下:

NSOperationQueue *queue = [[NSOperationQueue alloc] init];    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"1-----%@", [NSThread  currentThread]);    }];    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{        NSLog(@"2-----%@", [NSThread  currentThread]);    }];    [op2 addDependency:op1];    // 让op2 依赖于 op1,则先执行op1,在执行op2    [queue addOperation:op1];    [queue addOperation:op2];

执行结果是:op1先执行,op2后执行;


以上是学习后的一些总结,有什么错误的还请各位指点

0 0
原创粉丝点击