Я создал тестовый проект, в котором я проверяю свои предположения о NSOperation
и NSOperationQueue
, прежде чем использовать их в своем основном коде. проект.
Мой код довольно прост, поэтому я приведу его целиком. Это использует проект Foundation командной строки с включенным ARC.
#import <Foundation/Foundation.h>
@interface Operation : NSOperation
@property (readwrite, strong) NSString *label;
- (id)initWithLabel: (NSString *)label;
@end
#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
и когда это ожидание укусит меня каким-то образом, от которого я не могу защититься?