1

我知道我会得到“应该使用 OperationQueues”,但我在原始实现中遇到了问题。事实上,我遇到了与此相同的错误。两者都让我感到困惑,但这个更是如此。

我有一个同步的 add 方法,operations并且工作人员也同步了。

问题是被挑选的对象(至少据我所知)不应该在列表中。然后它对同一个调用执行两次并跳过第一次。

因此,如果添加了 ABC。它可能会执行 ACC 并且 B 甚至不会出现。没有其他班级可以看到operations,唯一增加它的是addOperation

程序的一些输出。

[Queue Manager] Adding new operation [ 111 ] is <SendOperation: 0x1dd5c510>
[Queue Manager] executing operation [ 112 ]  is <SendOperation: 0x1dd5c510>
[Operation]  executing [ 112 ]
[Queue Manager] Adding new operation [ 112 ] is <SendOperation: 0x1dd266e0>
[Queue Manager] executing operation [ 112 ]  is <SendOperation: 0x1dd266e0>

它得到正确的地址。但是号码错了。该数字只是 Operation 对象中的一个 int。它只在建筑上出现过。它没有设置器,也没有被修改过。

这里发生了什么?

看起来好像以某种方式将其复制到另一个地址?

#import "MyOperationQueue.h"
#import "Operation.h"
@implementation MyOperationQueue

NSMutableArray *operations;
NSCondition *condition;

-(id) init {
    self = [super init];
    if(self != nil) {
        operations = [[NSMutableArray alloc] init];
        condition = [[NSCondition alloc] init];
    }
    return self;
}

- (void) start{
    [self performSelectorInBackground:@selector(run) withObject:self];
}

-(void)run{
    while(YES){

        [condition lock];
        [condition wait];

        NSMutableArray *buffer = [[NSMutableArray alloc] init];
        @synchronized(operations){
            while([operations count] != 0 ) {
                Operation *operation = [operations objectAtIndex:0];
                [operations removeObject:operation];

                NSLog(@"[Queue Manager] executing operation %i is %@",[operation getNumber],operation);
                [operation execute];
            }
        }
        [condition unlock];
    }

}

-(void)addOperation:(id)operation{
    @synchronized(operations){ 
        NSLog(@"[Queue Manager] Adding new operation [ %i ] is %@",[operation getNumber],operation);
        [operations addObject:(operation)];
    }
    [sendCondition signal];
}

@end


@implementation Operation

int idNumber;

-(id) initWithIdNumber:(int)idNumber_{
    self = [super init];
    if( self ) {
        idNumber = idNumber_;
    }
    return self;
}


- (void) execute{
    NSLog(@"[Operation]  executing [ %i ]",idNumber);
}

-(int) getIdNumber{
    return idNumber;
}

@end
4

1 回答 1

0

这是您Operation实施的开始:

@implementation Operation

int idNumber;

如果你认为idNumber是实例变量,那你就错了。您已经声明了一个名为的全局变量idNumber。有关更多详细信息,请阅读此答案。这个错误被描述为“选项 2”。

如果要声明(私有)实例变量,请执行以下操作:

@implementation Operation {
    int _idNumber; // The _ prefix is a common Objective-C convention.
}

使用你@interface这样声明的属性会更好:

@interface Operation: NSObject

@property (nonatomic, readonly) int idNumber;

如果您将其声明为这样的readonly属性,

  • 编译器_idNumber为您生成实例变量,因此您可以删除实例变量声明,并且
  • 编译器会生成一个idNumber为您命名的 getter 方法,因此您可以删除您的getIdNumber方法。

您在. operations_condition@implementation MyOperationQueue

于 2019-05-24T18:05:27.347 回答