NSOperation instances have an internal state machine, which is shown in the diagram below.


The state machine for how NSOperation works.

The cancelled state can be entered to at any time, but it doesn't actually do anything as far as execution works. Subclasses of NSOperation should be mindful of checking cancelled appropriately such as before executing, and perhaps even periodically during execution.

Operation extends this state machine to support primary features of observers and *conditions.


The state machine for Operation class, which adds observers and conditions.

Evaluating Conditions

The evaluating condition state is entered after the operation's dependencies finish. During this stage the operation's conditions are evaluated asynchronously. Upon completion, the operation moves to the ready, while if there are no conditions to begin with, it goes directly to the ready state.


Operation Conditions

Read about Operation Conditions in more detail.


When an NSOperation becomes ready its main() function is invoked. Although not shown in the state machine, at this point an Operation subclass may have been cancelled or collected some errors, such as if conditions failed. In which case it moves to finishing without executing. Otherwise, it notifies observers that it did start, and execute() is called. This is the class which subclasses must override.


Once work has been done, the operation must finish. From within execute() it should call finish() which will move the operation to the finishing state. From this state, Operation calls finished() with any errors, then notifies any relevant observers that the operation did finish. These are opportunities for to perform actions when an operation finishes, either by internally by subclassing, or externally by observing. Then the operation moves to finished. There is no way to prevent and operation from transitioning from the finishing to finished states.


Operation Observers

Read about Operation Observers in more detail.


At any point it is possible to call cancel() or cancelWithError(). When this happens, the operation moves to cancelled. If the state is further along than ready, the operation will call finish().