Serial NSOperation
У меня есть Table View Controller с коллекцией ячеек, каждая ячейка отображает 2 значения:
-------------------------
| cell1 | val1 | val2 |
-------------------------
| cell2 | val1 | val2 |
-------------------------
...
Мне нужно выполнить последовательную синхронную операцию с этими ячейками с алгоритмом, подобным этому:
- настроить основные данные и обновить tableView UI
- итерировать клетки
2.1 обновить tableViewCell UI
2.2 итерация значений
2.2.1 обновить значение пользовательского интерфейса
2.2.2 загрузить новое значение
2.2.2.1, если не удалось повторить итерацию
2.2.3 интерфейс сохранения и обновления значений
2.3 обновление tableViewCell UI- сохранить и обновить tableView UI
Я использую NSOperationQueue с NSBlockOperations:
- (void)startOperation:(id)sender {
operationQueue = [NSOperationQueue new];
operationQueue.name = @"Operation Queue";
operationQueue.maxConcurrentOperationCount = 1;
[operationQueue waitUntilAllOperationsAreFinished];
NSBlockOperation * prepareCoreData = [[NSBlockOperation alloc] init];
[prepareCoreData addExecutionBlock:^{
NSLog(@"Prepare Core Data");
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"Update tableView UI");
}];
}];
[operationQueue addOperation:prepareCoreData];
NSBlockOperation * iterateCells = [[NSBlockOperation alloc] init];
__weak NSBlockOperation * weakIterateCells = iterateCells;
[iterateCells addExecutionBlock:^{
for (Item * item in self.items.fetchedObjects) {
if ([weakIterateCells isCancelled]) break;
NSBlockOperation * setCellUI = [[NSBlockOperation alloc] init];
[setCellUI addExecutionBlock:^{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@" Set tableViewCell UI");
}];
}];
[operationQueue addOperation:setCellUI];
NSBlockOperation * iterateValues = [[NSBlockOperation alloc] init];
__weak NSBlockOperation * weakIterateValues = iterateValues;
[iterateValues addExecutionBlock:^{
for (SearchEngine * s in self.searchEngines) {
if ([weakIterateValues isCancelled]) break;
NSBlockOperation * setValueUI = [[NSBlockOperation alloc] init];
[setValueUI addExecutionBlock:^{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@" Set Value UI");
}];
}];
[operationQueue addOperation:setValueUI];
NSBlockOperation * getValue = [[NSBlockOperation alloc] init];
[getValue addExecutionBlock:^{
NSLog(@" Download Value");
}];
[getValue addDependency:setCellUI];
[operationQueue addOperation:getValue];
NSBlockOperation * updateValue = [[NSBlockOperation alloc] init];
[updateValue addExecutionBlock:^{
NSLog(@" Save Data");
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@" Update Value UI");
}];
}];
[updateValue addDependency:getValue];
[operationQueue addOperation:updateValue];
}
}];
[iterateValues addDependency:setCellUI];
[operationQueue addOperation:iterateValues];
NSBlockOperation * updateCellUI = [[NSBlockOperation alloc] init];
[updateCellUI addExecutionBlock:^{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@" Update tableViewCell UI");
}];
}];
[updateCellUI addDependency:iterateValues];
[operationQueue addOperation:updateCellUI];
};
}];
[iterateCells addDependency:prepareCoreData];
[operationQueue addOperation:iterateCells];
NSBlockOperation * completeOperation = [[NSBlockOperation alloc] init];
[completeOperation addExecutionBlock:^{
NSLog(@"Save Data");
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"Update tableView UI");
}];
}];
[completeOperation addDependency:iterateCells];
[operationQueue addOperation:completeOperation];
}
С этим кодом последняя операция (#3) выполняется до того, как будут выполнены все итерации.
Я ищу предложения о том, как правильно вкладывать операции и очереди для поддержания последовательного порядка.