Я тот, кто считает, что это очень хорошая идея, поэтому я даже создал библиотеку после нее: CompositeOperations .
Существует две операции: простая операция, представленная COSimpleOperation
объектом, и составная операция, представленная COCompositeOperation
объектом.
Простая операция - наименьшая возможная единица - процитировать документацию:
В двух словах, COSimpleOperation - это NSOperation с небольшим количеством удобного сахара поверх него. Как операционная единица для составных операций, она обычно соответствует одному сетевому запросу или небольшому фрагменту работы.
Составная операция - это операция, которая состоит из подопераций. Процитирую @mikelikespie:
Цель этого объекта - сделать так, чтобы можно было представлять несколько операций, которые логически сгруппированы как одна операция.
... это еще одно описание Composite Design Pattern от Gang of Four Design Patterns.
Составная операция может быть parallel
или sequential
.
Параллельные операции создаются так же, как в рассматриваемом примере кода:
NSArray *operations = @[
operation1, operation2, operation3
]; // each operation is NSOperation <COOperation> *
COCompositeOperation *parallelOperation = [[COCompositeOperation alloc] initWithOperations:operations];
Для создания последовательной операции необходимо создать экземпляр COCompositeOperation с объектом, соответствующим протоколу COSequence
:
Последовательная композиция подразумевает последовательный поток: подоперации выполняются последовательно одна за другой. Секвенирование достигается за счет сотрудничества между COCompositeOperation и произвольным классом, соответствующим протоколу COSequence, который используется составной операцией в качестве делегата, который решает, какие операции и в каком порядке их запускать.
Чтобы сделать эту композицию операций возможной, мне нужно было наложить небольшое ограничение на работу библиотеки операций с: помимо того, что NSOperations, COSimpleOperation и COCompositeOperation также соответствуют протоколу <COOperation>
:
Это соответствие в основном означает, что обе операции после завершения имеют 3 возможных состояния:
непустое поле результата указывает на успех
непустое поле ошибки указывает на сбой
как пустые поля результатов, так и поля ошибок указывают, что операция была отменена извне (с использованием метода [NSOperation cancel]).
Операция никогда не может содержать поля результата и ошибки не пустыми!
Это соглашение позволяет составным операциям решать в определенный момент, продолжать ли выполнение определенной группы операций или остановить ее. Для операций без определенного результата [NSNull null] должен быть передан как результат.
Для меня рациональной основой этой библиотеки было «просто» представлять операции так, чтобы «они логически сгруппировались как одна операция». Существуют библиотеки, которые достигают такого же рода функциональности более высокого уровня, но в то же время они вводят такие понятия, как: Сигналы в ReactiveCocoa или Обещания, как в PromiseKit , которые я не очень нужно или я бы сказал не согласен с. Я хотел что-то как можно более простое и основанное на старой доброй хорошо известной инфраструктуре NSOperation / NSOperationQueue, так что в этом смысл всей работы.
P.S. Я надеюсь, что такой ответ подходит SO, по крайней мере, он точно соответствует тому, что @mikelikespie спрашивал около 4 лет назад.