• NSOperation 简介


    常用子类:

    NSOperation是一个基类,不应该直接生成NSOperation对象,而是应该用它的子类。

    • NSInvocationOperation
      • 将特定对象的特定方法封装成NSOperation
    • NSBlockOperation
      • 将代码块封装成NSOpreation

    示例:

    创建NSInvocationOperation

    NSString* url = @"http://www.xxx.com";
    //以self的downloadImageFromURL:方法作为执行体,创建NSOperation
    NSInvocationOperation* operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downloadImageFromURL:) object:url];	 
    

    创建NSBlockOperation

    NSBlockOperation* operation = [NSBlockOperation blockOperationWithBlock:^{
    	//执行体
    	...
    }];
    

    常用状态:

    可以通过KVO监听NSOperation的状态

    • isCancelled
    • isAsynchronous
    • isExecuting
    • isFinished
    • isReady

    执行任务

    创建了一个NSBlockOperation,并且设置好它的block,也就是将要执行的任务。这个任务会在主线程中执行。

    调用start方法让NSOperation方法运行起来。start是一个同步方法。

    在当前任务状态和依赖关系合适的情况下,启动NSOperation的main方法任务,需要注意缺省实现只是在当前线程运行。如果需要并发执行,子类必须重写这个方法,并且使 - (BOOL)isConcurrent 方法返回YES

    let operation = NSBlockOperation { () -> Void in  
    	print(NSThread.currentThread())
    }
    operation.addExecutionBlock { () -> Void in  
    	print("execution block1 --(NSThread.currentThread())")
    }
    operation.start()
    

    默认的NSOperation是同步执行的。简单的看一下NSOperation类的定义会发现它有一个只读属性asynchronous

    这意味着如果想要异步执行,就需要自定义NSOperation的子类。或者使用NSOperationQueue

    取消任务

    如果我们有两次网络请求,第二次请求会用到第一次的数据。如果此时网络情况不好,第一次请求超时了,那么第二次请求也没有必要发送了。当然,用户也有可能人为地取消某个NSOperation。

    当某个NSOperation被取消时,我们应该尽可能的清除NSOperation内部的数据并且把cancelled和finished设为true,把executing设为false。

    //取消某个NSOperation
    operation1.cancel()
    
    //取消某个NSOperationQueue剩余的NSOperation
    queue.cencelAllOperations()
    

    获取状态

    • @property(readonly, getter=isCancelled) BOOL cancelled
      • 当前任务状态是否已标记为取消
    • @property(readonly, getter=isExecuting) BOOL executing
      • 当前任务状态是否已标记为取消
    • @property(readonly, getter=isFinished) BOOL finished
      • NSOperation任务是否已结束
    • @property(readonly, getter=isConcurrent) BOOL concurrent
    • @property(readonly, getter=isAsynchronous) BOOL asynchronous
    • @property(readonly, getter=isReady) BOOL ready
      • NSOperation任务是否已结束
    • @property(copy) NSString *name

    等待

    • -(void)waitUntilFinished

        NSBlockOperation *opB = [NSBlockOperation blockOperationWithBlock:^{
        	[opA waitUntilFinished]; //opB线程等待直到opA执行结束(正常结束或被取消)
        	[self operate];
        }]; 
      

    设置依赖

    依然考虑刚刚所说的两次网络请求的例子。因为第二次请求会用到第一次的数据,所以我们要保证发出第二次请求的时候第一个请求已经执行完。但是我们同时还希望利用到NSOperationQueue的并发特性(因为可能不止这两个任务)。

    这时候我们可以设置NSOperation之间的依赖关系。语法非常简洁:

    operation2.addDependency(operation1)
    

    需要注意的是NSOperation之间的相互依赖会导致死锁

    移除依赖:

    - (void)removeDependency:(NSOperation *)operation
    

    优先级

    GCD中,任务(block)是没有优先级的,而队列具有优先级。和GCD相反,我们一般考虑NSOperation的优先级

    NSOperation有一个NSOperationQueuePriority枚举类型的属性queuePriority

    typedef enum : NSInteger {
    	NSOperationQueuePriorityVeryLow = -8,
    	NSOperationQueuePriorityLow = -4,
    	NSOperationQueuePriorityNormal = 0,
    	NSOperationQueuePriorityHigh = 4,
    	NSOperationQueuePriorityVeryHigh = 8
    } NSOperationQueuePriority;
  • 相关阅读:
    Exadata存储节点的CPU限制成功了没?
    如何减少Exadata计算节点CPU的Core数量
    如何选择适合你的HTAP数据库?
    小知识:Oracle中的层次查询
    小知识:使用MOS下载Oracle介质快速参考
    小知识:Flex ASM特性对集群资源显示的影响
    javaWeb request请求乱码、response响应中文乱码一站式解决方案
    java 文件File与byte[]数组相互转换的两种方式
    pr 如何调高导出视频的清晰度?
    pr 剪辑视频之剃刀用法
  • 原文地址:https://www.cnblogs.com/sunyanyan/p/5364552.html
Copyright © 2020-2023  润新知