NSOperation操作解析

翻译的比较烂,请见谅!
参考:https://developer.apple.com/library/mac/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationObjects/OperationObjects.html#//apple_ref/doc/uid/TP40008091-CH101-SW1

默认方式下,operations对象习惯性的异步执行,执行操作在一个线程中由start方法唤起,因为operation queue 为非并发的operationS提供线程,尽管许多operation还是异步执行。

然而如果你计划手动操作operations同时也希望他们仍然异步执行,你必须适当的执行一些操作确保他们可以运行。你这样做的效果是使你的operation对象并发运行。这时需要按照下面的法方进行重写操作。



NSOpertaion 的子类可以选择2中执行方式

1:non-concurrent  非并发的 ,可以限制并发数

这种方式是将NSOpertaion的子类添加到NSOpertaionQuene中,并且重写NSOpertaion的main函数即可,(执行顺序为添加顺序)

2: concurrent 并发的

重写下面的方法

• start

  • isConcurrent
  • isExecuting
  • isFinished

同时注意键值变化,必须保证是线程安全的

在这种并发的操作中,start消息用于启动这次异步操作,在这个消息中需要通过KVO 报告executing 状态(YES),这可以让感兴趣的操作端知道这个操作在执行中,同时注意该值的线程安全

一旦完成或者取消这次operation,必须通过KVO通知executing(NO)finished(YES)

状态,在取消状态中报告finished(YES)也是必须的,即使这次操作没有全部完成,如果在queue中,必须在删除操作之前报告状态的改变

 NSInvocationOperation使用这个类,可以避免在程序中为了每一个任务去创建大量的operation.其实这个类就是子类化了NSOperation,同时他需要添加到NSOperationQueue中,否则他不会自动异步执行。如果你手动start,则他是堵塞进程的,(因为你可能没有重载isexecuting 等函数)。



@interface MyOperation : NSOperation {


    BOOL        executing;


    BOOL        finished;


}


- (void)completeOperation;


@end


 


@implementation MyOperation


- (id)init {


    self = [super init];


    if (self) {


        executing = NO;


        finished = NO;


    }


    return self;


}


 


- (BOOL)isConcurrent {


    return YES;


}


 


- (BOOL)isExecuting {


    return executing;


}


 


- (BOOL)isFinished {


    return finished;


}


@end

- (void)start {


   // Always check for cancellation before launching the task.


   if ([self isCancelled])


   {


      // Must move the operation to the finished state if it is canceled.


      [self willChangeValueForKey:@"isFinished"];


      finished = YES;


      [self didChangeValueForKey:@"isFinished"];


      return;


   }


 


   // If the operation is not canceled, begin executing the task.


   [self willChangeValueForKey:@"isExecuting"];


   [NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil];


   executing = YES;


   [self didChangeValueForKey:@"isExecuting"];


}

- (void)main {


   @try {


 


       // Do the main work of the operation here.


 


       [self completeOperation];


   }


   @catch(...) {


      // Do not rethrow exceptions.


   }


}


 


- (void)completeOperation {


    [self willChangeValueForKey:@"isFinished"];


    [self willChangeValueForKey:@"isExecuting"];


 


    executing = NO;


    finished = YES;


 


    [self didChangeValueForKey:@"isExecuting"];


    [self didChangeValueForKey:@"isFinished"];


}


重写这些方法时在任何核实后都不需要调用super

 the main method is the entry point for a new thread.

main方法是新线程的入口点,在main中完成同步操作,如果main中需要执行一步操作,则需要注意main的提前结束,需要同步main函数才行。

isConcurrent 表示是否并发操作,返回YES表示并发。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值