美文网首页
NSOperation和NSOperationQueue

NSOperation和NSOperationQueue

作者: Hollylord | 来源:发表于2015-06-09 10:42 被阅读363次

    NSOperation

    1.继承NSOperation类

    2.重写“main”方法

    3.在“main”方法中创建一个“autoreleasepool”

    4.将你的代码放在“autoreleasepool”中

    取消任务:

    这里关键是要经常地检查NSOperation类的isCancelled属性。

    - (void)main {

        // a lengthy operation 

        @autoreleasepool {

        for (int i = 0 ; i < 10000 ; i++) {

        // is this operation cancelled?

          if (self.isCancelled)

          break;

          NSLog(@"%f", sqrt(i));

          }

        }

    }

    为了取消这个操作,你应该调用NSOperation的取消方法,正如下面的:

    [my_lengthy_operation cancel];

    从属性(Dependency):

    你可以让一个操作从属于其他的操作。任何操作都可以从属于任意数量的操作。当你让操作A从属于操作B时,即使你调用了操作A的“start”方法,它会等待操作B结束后才开始执行。例如:

    MyDownloadOperation *downloadOp = [[MyDownloadOperation alloc] init]; // MyDownloadOperation is a subclass of NSOperation

    MyFilterOperation *filterOp = [[MyFilterOperation alloc] init]; // MyFilterOperation  is a subclass of NSOperation

    [filterOp addDependency:downloadOp];

    要删除依赖性:

    [filterOp removeDependency:downloadOp];

    优先级(Priority):

    有时候你希望在后台运行的操作并不是很重要的,它可以以较低的优先级执行。可以通过使用“setQueuePriority:”方法设置一个操作的优先级。

    [filterOp setQueuePriority:NSOperationQueuePriorityVeryLow];

    其他关于设置线程优先级的选择有: NSOperationQueuePriorityLow, NSOperationQueuePriorityNormal, NSOperationQueuePriorityHigh和NSOperationQueuePriorityVeryHigh.

    当你添加了操作到一个队列时,在对操作调用“start”方法之前,NSOperationQueue会浏览所有的操作。那些有较高优先级的操作会被先执行。有同等优先级的操作会按照添加到队列中的顺序去执行(先进先出)。

    Completion block:

    在NSOperation 类中另一个有用的方法叫setCompletionBlock:。一旦操作完成了,如果你还有一些事情想做,你可以把它放在一个块中,并且传递给这个方法。这个块会在主线程中执行。

    你一旦添加了一个操作到一个队列(NSOperationQueue的一个实例)中,就要负责释放它(如果你不使用ARC的话)。NSOperationQueue获得操作对象的所有权,调用“start”方法,然后结束时负责释放它。

    你不能重用一个操作对象。一旦它被添加到一个队列中,你就丧失了对它的所有权。如果你想再使用同一个操作类,就必须创建一个新的实例变量。

    一个结束的操作不能被重启。

    一个操作是否成功地完成,失败了,或者是被取消了,isFinished的值总会被设置为YES。所以千万不要觉得isFinished==YES就表示所有的事情都顺利完成了—特别的,如果你在代码里面有从属性(dependencies),就要更加注意!

    NSOperationQueue

    并发操作:

    队列和线程是两个不同的概念。一个队列可以有多个线程。每个队列中的操作会在所属的线程中运行。举个例子你创建一个队列,然后添加三个操作到里面。队列会发起三个单独的线程,然后让所有操作在各自的线程中并发运行。

    并发操作的最大值:

    你可以设定NSOperationQueue可以并发运行的最大操作数。NSOperationQueue会选择去运行任何数量的并发操作,但是不会超过最大值。

    myQueue.MaxConcurrentOperationCount = 3;

    如果你改变了主意,想将MaxConcurrentOperationCount设置回默认值,你可以执行下列操作:

    myQueue.MaxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount;

    添加操作:

    一个操作一旦被添加到一个队列中,你就应该通过传送一个release消息给操作对象(如果使用了手动引用计数,非ARC的话),然后队列会负责开始这个操作。从这点上看,什么时候调用“start”方法由这个队列说了算。

    [myQueue addOperation:downloadOp];

    [downloadOp release]; // manual reference counting

    待处理的操作:

    任何时候你可以询问一个队列哪个操作在里面,并且总共有多少个操作在里面。记住只有那些等待被执行的操作,还有那些正在运行的操作,会被保留在队列中。操作一完成,就会退出队列。

    NSArray *active_and_pending_operations = myQueue.operations;

    NSInteger count_of_operations = myQueue.operationCount;

    暂停队列:

    你可以通过设定setSuspended:YES来暂停一个队列。这样会暂停所有在队列中的操作 — 你不能单独的暂停操作。要重新开始队列,只要简单的setSuspended:NO。

    // Suspend a queue

    [myQueue setSuspended:YES];

    取消操作:

    要取消一个队列中的所有操作,你只要简单的调用“cancelAllOperations”方法即可。还记得之前提醒过经常检查NSOperation中的isCancelled属性吗?

    原因是“cancelAllOperations”并没有做太多的工作,他只是对队列中的每一个操作调用“cancel”方法 — 这并没有起很大作用!:] 如果一个操作并没有开始,然后你对它调用“cancel”方法,操作会被取消,并从队列中移除。然而,如果一个操作已经在执行了,这就要由单独的操作去识别撤销(通过检查isCancelled属性)然后停止它所做的工作。

    [myQueuecancelAllOperations];

    addOperationWithBlock: 

    如果你有一个简单的操作不需要被继承,你可以将它当做一个块(block)传递给队列。如果你需要从块那里传递回任何数据,记得你不应该传递任何强引用的指针给块;相反,你必须使用弱引用。而且,如果你想要在块中做一些跟UI有关的事情,你必须在主线程中做。

    UIImage *myImage = nil;

    // Create a weak reference

    __weak UIImage *myImage_weak = myImage;

    // Add an operation as a block to a queue

    [myQueue addOperationWithBlock: ^ {

    // a block of operation

    NSURL *aURL = [NSURL URLWithString:@"http://www.somewhere.com/image.png"];

    NSError *error = nil;

    NSData *data = [NSData dataWithContentsOfURL:aURL options:nil error:&error];

    If (!error)

    [myImage_weak imageWithData:data];

    // Get hold of main queue (main thread)

    [[NSOperationQueue mainQueue] addOperationWithBlock: ^ {

    myImageView.image = myImage_weak; // updating UI

    }];

    }];

    相关文章

      网友评论

          本文标题:NSOperation和NSOperationQueue

          本文链接:https://www.haomeiwen.com/subject/vmcjqttx.html