来自 电脑系统 2019-09-15 04:19 的文章
当前位置: 金沙澳门官网网址 > 电脑系统 > 正文

详细计算

开发过程中为了保证界面操作的流畅,很多操作都需要放在子线程去执行,以免阻塞主线程。这时就需要多线程的知识了。

金沙澳门官网网址 1

平常使用多线程的地方很多第三方库已经进行了封装,比如AFNetworking、SDWebImage等,使用者不需去关心异步的操作。

  • 本文首发于我的个人博客:『不羁阁』
  • 文章链接:传送门
  • 本文更新时间:2018年03月06日17:27:55

笔者对之前写的原文重新整理,修改了部分内容,又增加了许多关于 NSOperation、NSOperationQueue 的知识及用法,希望大家喜欢。

本文用来介绍 iOS 多线程中 NSOperation、NSOperationQueue 的相关知识以及使用方法。

通过本文,您将了解到:NSOperation、NSOperationQueue 简介操作和操作队列使用步骤和基本使用方法控制串行/并发执行NSOperation 操作依赖和优先级线程间的通信线程同步和线程安全,以及 NSOperation、NSOperationQueue 常用属性和方法归纳

文中 Demo 我已放在了 Github 上,Demo 链接:传送门

多线程的使用通常有3种方式:1.NSThread2.GCD3.NSOperation

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

本文主要讲解NSOperation的使用

为什么要使用 NSOperation、NSOperationQueue?

NSOperation是抽象类,一般不直接使用,可以使用其子类:NSInvocationOperation, NSBlockOperation,或者继承NSOperation重写其特定的一些方法
  1. 可添加完成的代码块,在操作完成后执行。
  2. 添加操作之间的依赖关系,方便的控制执行顺序。
  3. 设定操作执行的优先级。
  4. 可以很方便的取消一个操作的执行。
  5. 使用 KVO 观察对操作执行状态的更改:isExecuteing、isFinished、isCancelled。
1.NSInvocationOperation
- viewDidLoad{ [super viewDidLoad]; //创建NSInvocationOperation对象 NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector object:@"123"]; //开始执行 [op start];}- test:(NSString *)str{ //do sth NSLog(@"%@",[NSThread currentThread]);}某次运行结果:<NSThread: 0x7f9058d07cc0>{number = 1, name = main}

注意:number表示线程编号,1为主线程。由运行结果可以看出直接使用仍然是在主线程中执行的。

既然是基于 GCD 的更高一层的封装。那么,GCD 中的一些概念同样适用于 NSOperation、NSOperationQueue。在 NSOperation、NSOperationQueue 中也有类似的任务队列的概念。

2.NSBlockOperation
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"第一个:%@",[NSThread currentThread]);}];[op addExecutionBlock:^{ NSLog(@"第二个:%@",[NSThread currentThread]);}];[op addExecutionBlock:^{ NSLog(@"第三个:%@",[NSThread currentThread]);}];[op start];某次运行结果:第一个:<NSThread: 0x7fbf13c027a0>{number = 1, name = main}第三个:<NSThread: 0x7fbf13c119b0>{number = 3, name = }第二个:<NSThread: 0x7fbf13d11040>{number = 2, name = }

注意:由运行结果可知 第一个一定是主线程中运行的,addExecutionBlock中的会另起线程并发执行,执行顺序不定。

  • 操作(Operation):
    • 执行操作的意思,换句话说就是你在线程中执行的那段代码。
    • 在 GCD 中是放在 block 中的。在 NSOperation 中,我们使用 NSOperation 子类 NSInvocationOperationNSBlockOperation,或者自定义子类来封装操作。
  • 操作队列(Operation Queues):
    • 这里的队列指操作队列,即用来存放操作的队列。不同于 GCD 中的调度队列 FIFO的原则。NSOperationQueue 对于添加到队列中的操作,首先进入准备就绪的状态(就绪状态取决于操作之间的依赖关系),然后进入就绪状态的操作的开始执行顺序由操作之间相对的优先级决定(优先级是操作对象自身的属性)。
    • 操作队列通过设置金沙澳门官网网址 ,最大并发操作数(maxConcurrentOperationCount)来控制并发、串行。
    • NSOperationQueue 为我们提供了两种不同类型的队列:主队列和自定义队列。主队列运行在主线程之上,而自定义队列在后台执行。
3.继承NSOperation

重写 - mian 方法。此方法中的操作在此线程中是同步执行的。

@implementation MyOperation- main{ //do sth NSLog(@"MyOperation main : %@",[NSThread currentThread]);}//使用方法MyOperation *op = [[MyOperation alloc] init];[op start];某次运行结果:MyOperation main : <NSThread: 0x7fb85a705060>{number = 1, name = main}

若要自己定义异步执行就需要重写- start方法,此时会执行start方法不会去执行main方法,需要注意的是需要我们自己去管理operation的状态。

//这两个属性在父类中为readonly,子类需要复写@property (nonatomic, assign) BOOL finished;@property (nonatomic, assign) BOOL executing;- start{ if ([self isCancelled]) { _finished = YES; return; } else { _executing = YES; //开始异步 //完成异步 if ([self isCancelled]) { //每做完一些异步操作就需要判断是否取消 _executing = NO; _finished = YES; return; } else { //do sth _executing = NO; _finished = YES; } }}//需要手动发送KVO通知- setFinished:finished{ [self willChangeValueForKey:@"isFinished"]; _finished = finished; [self didChangeValueForKey:@"isFinished"];}//需要手动发送KVO通知- setExecuting:executing{ [self willChangeValueForKey:@"isExecuting"]; _executing = executing; [self didChangeValueForKey:@"isExecuting"];}

NSOperation 需要配合 NSOperationQueue 来实现多线程。因为默认情况下,NSOperation 单独使用时系统同步执行操作,配合 NSOperationQueue 我们能更好的实现异步执行。

4.NSOperationQueue

前3个若直接使用都会在主线程中执行,这是我们更所不期望看到的,此时需要借助NSOperationQueue对象,此对象会把需要执行的Operation加入到一个队列中,然后并发执行队列中的Operation。

//创建队列NSOperationQueue *queue = [[NSOperationQueue alloc] init];//创建操作MyOperation *op = [[MyOperation alloc] init];//将操作加入队列即可[queue addOperation:op];

** 注意:1.此处不要调用start 方法。2.加入队列后会自动并发执行。全部都开启线程,不在主线程中执行。3.NSOperationQueue有属性maxConcurrentOperationCount可以设置最大并发执行数,若设置为1,则效果为FIFO。**

NSOperation 实现多线程的使用步骤分为三步:

本文由金沙澳门官网网址发布于电脑系统,转载请注明出处:详细计算

关键词: