iOS之[多线程:NSOperation]

你离开我真会死。 提交于 2020-01-07 06:16:06

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

1. NSOperation

:fa-exclamation-triangle:以下是你需要考虑使用 NSOperation 的一些理由:

1.当你需要取消线程任务时,GCD 无法提供取消任务的操作。而 NSOperation 提供了取消任务的操作;

2.当你需要更细的粒度地观察任务改变了状态时,由于 NSOperation 是一个对象,比较 GCD 使用的 block 而言,通过对 NSOperation 对象进行键值观察(KVO)能很容易观察到任务的状态改变;

3.当你需要重用线程任务时,NSOperation 作为一个普通的 Objective-C 对象,可以存储任何信息。对象就是为重用而设计的,这时,NSOperation 比 GCD 使用的 block 要更方便。

1.1 NSOperation简介

实际开发中使用的是NSOperation的两个子类

    - NSInvocationOperation
    - NSBlockOperation        :使用block形式组织代码,相对方便
1.2 线程的创建执行过程
异步:创建NSOperation -> 创建NSOperationQueue队列 -> 将NSOperation添加到Queue中

同步:创建NSOperation -> 调用start方法
1.3 线程状态
isReady     :准备就绪 -> 只读(有线程依赖时可能为NO)
isExecuting :正在执行 -> 只读
isFinished  :执行完了 -> 只读
isCancelld  :已经取消 -> 可以手动干预:调用cancel()方法
    - 只是设置队列状态,并不是真正的停止当前队列
1.4线程优先级:queuePriority

线程优先级分为5个级别

@property double threadPriority; //IOS8已废弃
@property NSOperationQueuePriority queuePriority;

typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
	NSOperationQueuePriorityVeryLow = -8L,
	NSOperationQueuePriorityLow = -4L,
	NSOperationQueuePriorityNormal = 0,
	NSOperationQueuePriorityHigh = 4,
	NSOperationQueuePriorityVeryHigh = 8
};
1.5设置依赖线程

A依赖于B:B执行完之后,才能执行A 添加依赖

- (void)addDependency:(NSOperation *)op;

删除依赖

- (void)removeDependency:(NSOperation *)op;
1.6 添加执行完毕监听
operation.completionBlock = ^(){
    //执行完毕
};

- (void)waitUntilFinished;

2.NSOperationQueue

  • 负责管理/执行所有的NSOperation

  • 能够更加容易的管理线程总数,控制线程之间的依赖关系

2.1在队列中添加操作
- (void)addOperation:(NSOperation *)op;

- (void)addOperations:(NSArray<NSOperation *> *)ops waitUntilFinished:(BOOL)wait;

- (void)addOperationWithBlock:(void (^)(void))block;
2.2设置最大线程数
queue.maxConcurrentOperationCount = ?
2.3取消队列中所有线程
- (void)cancelAllOperations;
2.4执行完了监听
- (void)waitUntilAllOperationsAreFinished;
2.5调用主线程队列:更新UI
[[NSOperationQueue mainQueue] addOperation...];

3.NSInvocationOperation

创建线程:

- (instancetype)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
- (instancetype)initWithInvocation:(NSInvocation *)inv;

例子:

//创建操作
NSInvocationOperation *invocationOpr = 
        [[NSInvocationOperation alloc] initWithTarget:self 
                                             selector:@selector(load) 
                                               object:nil];

//创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

//添加到队列,队列回开启一个线程执行此操作
[queue addOperation : invocationOpr];

4.NSBlockOperation

创建线程

+ (instancetype)blockOperationWithBlock:(void (^)(void))block;

//在已有的线程的基础上,添加其他线程:并发
- (void)addExecutionBlock:(void (^)(void))block;

例子:

方法一:创建操作并添加到队列
    NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{
        
    }];

    //创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    //添加到队列
    [queue addOperation : block];

方法二:直接添加操作到队列
    //创建队列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    [queue addOperationWithBlock:^{
        
    }];    

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

其他线程方式:

NSThread http://my.oschina.net/u/2462423/blog/534210

GCD:Dispatch http://my.oschina.net/u/2462423/blog/534159

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!