IOS多线程之NSOperation

Posted R1cardo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IOS多线程之NSOperation相关的知识,希望对你有一定的参考价值。

IOS多线程之NSOperation(2)

最大并发数

open var maxConcurrentOperationCount: Int

并发数就是同时执行的任务数。比如,同时开3个线程执行3个任务,并发数就是3。
但是,并发数是3,并不代表开启的线程数就是3,也有可能是4个或者5个。因为线程有可能在等待,进入了就绪状态。

执行的过程:

  1. 把操作添加到队列;
  2. 去线程池去取空闲的线程,如果没有就创建线程;
  3. 把操作交给线程池中取出的线程执行;
  4. 执行完成后,把线程再放回线程池中;
  5. 重复2,3,4直到所有的操作都执行完。

GCD的区别

GCD会自动重用线程,而 NSOperation 不会,会一直开线程。
而开太多线程反而会影响效率,我们需要自己控制
可以通过最大并发数控制

let queue = OperationQueue()
queue.maxConcurrentOperationCount = 3
for _ in 0..<10
    queue.addOperation 
        sleep(1)
        print("\\(Thread.current)")
    

/*
<NSThread: 0x6000001e0e80>number = 4, name = (null)
<NSThread: 0x6000001e2d80>number = 7, name = (null)
<NSThread: 0x6000001fc340>number = 5, name = (null)
<NSThread: 0x6000001f8cc0>number = 8, name = (null)
<NSThread: 0x6000001e0e80>number = 4, name = (null)
*/

//打印时是3个3个打印的

队列的操作

//暂停
func suspend()
    queue.isSuspended = true

//继续
func resume()
    queue.isSuspended = false

//取消
func cancel()
    queue.cancelAllOperations()

Operation的状态

//取消
open var isCancelled: Bool  get 
//执行中
open var isExecuting: Bool  get 
//完成
open var isFinished: Bool  get 
//就绪
open var isReady: Bool  get 

控制Operation的状态

//启动
open func start()
//取消
open func cancel()

可以继承自定义MyOperation继承Operation类,重写startcancel方法来自己管理

let operation = MyOperation()
operation.start()
operation.cancel()

class MyOperation: Operation 
    override func start() 
        super.start()
        print("operation started")
    

    override func main() 
        super.main()
        print("operation main")
    

    override func cancel() 
        super.cancel()
        print("operation cancel")
    


/*
operation main
operation started
operation cancel
*/

iOS多线程之NSOperation的使用

  • NSOperation对象的使用步骤

NSOperation对象描述了一个操作任务;NSOperationQueue对象描述了一个任务队列,相当于GCD的dispatch_queue_t

NSOperation及NSOperationQueue可以任务是GCD之上的面向对象封装

GCD提供了更底层的控制,NSOperationQueue在GCD之上实现了一些方便的功能,这些功能对于开发者而言通常是最好最安全的选择

     

基本使用步骤 :

    1)定义操作队列

    2)定义操作

    3)将操作添加到队列

提示: 一旦将操作添加到队列,操作就会立即被调度执行


  • 任务队列对象

NSOperationQueue描述了任务队列,使用两种队列:

1)主队列,其中的任务只在主线程中执行,和GCD的主队列一样

+ (NSOperationQueue *)mainQueue

2)自定义队列,其中的任务会在子线程中执行,和GCD的全局队列一样

     使用alloc+init方式创建

NSOperationQueue的其他方法:

- (void)cancelAllOperations  //取消所有的任务
- (void)waitUntilAllOperationsAreFinished //等待至所有任务结束
@property NSInteger maxConcurrentOperationCount //队列中任务的最大并发数
@property(assign) dispatch_queue_t underlyingQueue //GCD的底层队列


  • 任务对象及其子类

NSOperation描述了一个任务,是一个抽象类型,应当使用其子类

     NSBlockOperation和NSInvocationOperation


1)NSBlockOperation使用block描述一个任务:

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

     还可以添加block,使其描述多个任务

- (void)addExecutionBlock:(void (^)(void))block

     

2)NSInvocationOperation使用方法一个任务:

- (instancetype)initWithTarget:(id)target selector:(SEL)sel object:(id)arg

     指定的方法可以有返回值,使用result属性获取

@property(readonly, retain) id result


  • 向任务度列中添加任务

    使用任务队列对象的addOperation方法:

- (void)addOperation:(NSOperation *)operation //不会阻塞当前线程的执行
- (void)addOperations:(NSArray<NSOperation *> *)ops waitUntilFinished:(BOOL)wait //可以阻塞当前线程

还有一种直接传递block的添加任务方式:

- (void)addOperationWithBlock:(void (^)(void))block


总结:三种添加任务的方式:

     1)addOperationWithBlock:

     2)添加NSBlockOperation任务

     3)添加NSInvocationOperation任务


  • 异步下载图片

任务1:bo1对象,描述了一个下载任务

任务2:bo2对象,将下载后的图像对象显示

     任务1添加到自定义任务队列中,在子线程执行

     任务2添加到主队列中,在主线程执行

    技术分享



  • 任务的依赖

通过任务的依赖可以方便地控制多个任务执行的先后顺序

使用NSOperation的addDependency:方法添加依赖

- (void)addDependency:(NSOperation *)operation

如:将上面的代码修改

    技术分享

     其中self.img是新添加的一个UIImage属性


本文出自 “teacherAn” 博客,请务必保留此出处http://annmeng.blog.51cto.com/3321237/1746634

以上是关于IOS多线程之NSOperation的主要内容,如果未能解决你的问题,请参考以下文章

iOS多线程之NSOperation的使用

iOS多线程开发之NSOperation - 快上车,没时间解释了!

IOS多线程之NSOperation

Ios 多线程之NSOperation与NSOprationQueue

IOS多线程之NSOperation

iOS多线程开发系列之NSOperation