我创建了一个测试项目,我在其中测试我的假设NSOperation
,NSOperationQueue
然后在我的主项目中使用它们。
我的代码非常简单,所以我将在此处包含所有代码。这是使用打开 ARC 的命令行 Foundation 项目。
操作.h
#import <Foundation/Foundation.h>
@interface Operation : NSOperation
@property (readwrite, strong) NSString *label;
- (id)initWithLabel: (NSString *)label;
@end
操作.m
#import "Operation.h"
@implementation Operation
- (void)main
{
NSLog( @"Operation %@", _label);
}
- (id)initWithLabel: (NSString *)label
{
if (( self = [super init] )) {
_label = label;
}
return self;
}
@end
主程序
#import <Foundation/Foundation.h>
#import "Operation.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
id create = [[Operation alloc] initWithLabel: @"create"];
id update1 = [[Operation alloc] initWithLabel: @"update1"];
id update2 = [[Operation alloc] initWithLabel: @"update2"];
[update1 addDependency: create];
[update2 addDependency: create];
[queue addOperation: update1];
[queue addOperation: create];
[queue addOperation: update2];
[queue waitUntilAllOperationsAreFinished];
}
return 0;
}
我的输出如下所示:
2012-05-02 11:37:08.573 QueueTest[1574:1b03] Operation create
2012-05-02 11:37:08.584 QueueTest[1574:1903] Operation update2
2012-05-02 11:37:08.586 QueueTest[1574:1b03] Operation update1
写完这个并尝试了一些组合后,我发现当我像这样重新排序队列设置时:
[queue addOperation: update1];
[queue addOperation: create];
[queue addOperation: update2];
[update1 addDependency: create];
[update2 addDependency: create];
[queue waitUntilAllOperationsAreFinished];
我得到了相同的输出:
2012-05-02 11:38:23.965 QueueTest[1591:1b03] Operation create
2012-05-02 11:38:23.975 QueueTest[1591:1b03] Operation update1
2012-05-02 11:38:23.978 QueueTest[1591:1903] Operation update2
我应该注意到,我在一些运行中发现 update2 在 update1 之前执行,但这种行为并不奇怪。NSOperationQueue
当我没有要求它是确定性时,为什么应该是确定性的?
我确实感到惊讶的是,即使在添加依赖项之前将所有内容都添加到队列中,create 总是在 update1 和 update2 之前执行。
显然,这是一件愚蠢的事情,但它让我想知道:我将操作添加到队列和执行它之间的延迟是否记录在案,或者以任何方式可预测?究竟什么时候NSOperationQueue
开始处理添加的操作?
真的,最重要的是,究竟是什么在NSOperationQueue
等待,什么时候等待以某种我无法防御的方式咬我?