NSOperationQueue:无法理解订单

时间:2013-11-26 18:14:37

标签: ios objective-c multithreading cocoa-touch objective-c-blocks

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

说我有:

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

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

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

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

我不太明白。帮帮我!!

1 个答案:

答案 0 :(得分:4)

如果操作之间存在明确的依赖关系,则使用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];

如果您的操作正在进行异步活动,那么您应该定义一个自定义操作,并且只在异步任务完成时调用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中启动的异步任务调用其{{1}之前,它将无法启动operation1方法。

completeOperation