This question already has answers here:
NSOperationQueue serial FIFO queue

(3个答案)


7年前关闭。




我无法理解NSOperationQueue的工作方式。

说我有:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
        queue.maxConcurrentOperationCount=1;

        [queue addOperationWithBlock:^{
[someObject someSelector];
}];

        [queue addOperationWithBlock:^{
[someObject anotherSelector];
}];

第二个块甚至在第一个块完成之前就被调用-与我想要的相反。我尝试使用– performSelectorOnMainThread:withObject:waitUntilDone:代替,但是第二个块仍在首先执行-大概是因为该块线程尚未在主线程上完成,所以它没有被waitUntilDone阻止。我在someSelector块内添加了一个断点,在第二个块内的断点后达到了断点。

我不太明白。帮我!!

最佳答案

如果操作之间存在明确的依赖关系,请使用addDependency:

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount=1;

NSOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
    [someObject someSelector];
}];

NSOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
    [someObject anotherSelector];
}];

[operation2 addDependency:operation1];

[queue addOperation:operation1];
[queue addOperation:operation2];

如果您的操作正在进行异步 Activity ,则应定义一个自定义操作,并在完成异步任务后仅调用completeOperation(它将发布isFinished消息)。
//  SomeOperation.h

#import <Foundation/Foundation.h>

@interface SomeOperation : NSOperation

@end


//  SomeOperation.m

#import "SomeOperation.h"

@interface SomeOperation ()
@property (nonatomic, readwrite, getter = isFinished)  BOOL finished;
@property (nonatomic, readwrite, getter = isExecuting) BOOL executing;
@end

@implementation SomeOperation

@synthesize finished  = _finished;
@synthesize executing = _executing;

#pragma Configure basic operation

- (id)init
{
    self = [super init];
    if (self) {
        _finished  = NO;
        _executing = NO;
    }
    return self;
}

- (void)start
{
    if ([self isCancelled]) {
        self.finished = YES;
        return;
    }

    self.executing = YES;

    [self main];
}

- (void)completeOperation
{
    self.executing = NO;
    self.finished  = YES;
}

- (void)main
{
    // start some asynchronous operation

    // when it's done, call `completeOperation`
}

#pragma mark - Standard NSOperation methods

- (BOOL)isConcurrent
{
    return YES;
}

- (void)setExecuting:(BOOL)executing
{
    [self willChangeValueForKey:@"isExecuting"];
    _executing = executing;
    [self didChangeValueForKey:@"isExecuting"];
}

- (void)setFinished:(BOOL)finished
{
    [self willChangeValueForKey:@"isFinished"];
    _finished = finished;
    [self didChangeValueForKey:@"isFinished"];
}

@end

因此,使用以下代码,只有在operation2对象main中的SomeOperation中启动的异步任务调用其operation1方法后,它才会启动completeOperation
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount=1;

NSOperation *operation1 = [[SomeOperation alloc] init];

NSOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
    [someObject anotherSelector];
}];

[operation2 addDependency:operation1];

[queue addOperation:operation1];
[queue addOperation:operation2];

09-09 22:15
查看更多