【发布时间】:2012-05-12 06:50:34
【问题描述】:
我创建了一个测试项目,我在其中测试我对NSOperation 和NSOperationQueue 的假设,然后在我的主项目中使用它们。
我的代码非常简单,所以我将在此处包含所有代码。这是使用启用了 ARC 的命令行 Foundation 项目。
操作.h
#import <Foundation/Foundation.h>
@interface Operation : NSOperation
@property (readwrite, strong) NSString *label;
- (id)initWithLabel: (NSString *)label;
@end
Operation.m
#import "Operation.h"
@implementation Operation
- (void)main
{
NSLog( @"Operation %@", _label);
}
- (id)initWithLabel: (NSString *)label
{
if (( self = [super init] )) {
_label = label;
}
return self;
}
@end
Main.m
#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 究竟在等待什么?等待何时会以某种我无法防御的方式咬我?
【问题讨论】:
-
我怀疑这在任何方面都是可预测或可靠的。这是一个经典的比赛条件。我想设置依赖关系的当前线程可能具有优势,因为它已经在运行,但不依赖于此。如果有任何机会让另一个线程开始做某事所花费的时间会“咬”你,那么你做错了。
-
谢谢肯。 :) 是的,我打算比我的测试代码更小心。但我的一部分天性是当我发现一些不应该工作的东西时,除了确定它应该工作我想了解它。 NSOperationQueue 从不同的线程运行并且(通常)不具有该边缘在这里最有意义。我想这会导致人们无法找到的错误。
标签: cocoa-touch cocoa nsoperationqueue