In iOS development, there is no escaping the use of multithreading. In the Foundation framework, GCDS written in C are generally the most frequently used, but not the most systematic. On the basis of GCD, Apple has encapsulated a layer of the class NSOperation, which has many methods and mechanisms to use, greatly facilitating our development. In learning, we try to familiarize ourselves with and master the high-level API first, and then familiarize ourselves with and master the underlying encapsulation. So, let’s talk about NSOperation today.

1.NSOperation cannot be used directly

NSOperation is an abstract class, and you usually use a subclass of it.

Its internal properties and methods:

– (void)start; // Either start, or put in queue, start execution. Same effect.

– (void)main;

@property (readonly, getter=isCancelled) BOOL cancelled;

– (void)cancel; // Cancel execution as opposed to start or queue execution.

@property (readonly, getter=isExecuting) BOOL executing;

@property (readonly, getter=isFinished) BOOL finished;

@property (readonly, getter=isConcurrent) BOOL concurrent;

@property (readonly, getter=isAsynchronous) BOOL asynchronous

@property (readonly, getter=isReady) BOOL ready;

– (void)addDependency:(NSOperation *)op;

– (void)removeDependency:(NSOperation *)op;

@property (readonly, copy) NSArray *dependencies;

@property NSOperationQueuePriority queuePriority;

Void (^completionBlock)(void) API_AVAILABLE(macOS (10.6), ios(4.0), watchos(2.0), tvos(9.0)); void (^completionBlock)(void) API_AVAILABLE(MacOS (10.6), ios(4.0), watchos(2.0), tvos(9.0));

Void waitUntilFinished API_AVAILABLE(MacOS (10.6), ios(4.0), Watchos (2.0), tVOs (9.0));

@property double threadPriority API_DEPRECATED(“Not supported”, MacOS (10.6,10.10), ios(4.0,8.0), watchos(2.0,2.0), Tvos (9.0, 9.0));

@property NSQualityOfService qualityOfService API_AVAILABLE(MacOS (10.10), ios(8.0), Watchos (2.0), TVOs (9.0));

@property (nullable, copy) NSString *name API_AVAILABLE(MacOS (10.10), ios(8.0), Watchos (2.0), tVOs (9.0));

The system API has two subclasses: NSBlockOperation and NSInvocationOperation. Of course, you can also customize subclasses to inherit NSOperation and implement internal corresponding methods.

The big difference between NSBlockOperation and NSInvocationOperation is that one is the block callback structure and the other is the target structure. Based on the basic differences in structure, there are many other structural differences in detail.

2. The use of NSBlockOperation

Methods and properties of NSBlockOperation.

+ (instancetype)blockOperationWithBlock:(void (^)(void))block;

– (void)addExecutionBlock:(void (^)(void))block;

@property (readonly, copy) NSArray *executionBlocks;

Example: 👇

Initializes an NSBlockOperation object that encapsulates the operation to be performed with a Block. Call the start method, and immediately execute the contents of the Block, again executing synchronously in the current thread, not asynchronously, blocking the main thread.




To implement multi-task operations, you need to use the addOperation method:





There are, of course, many more methods available to the parent class.

3. The use of NSInvocationOperation

Its methods and properties:

– (nullable instancetype)initWithTarget:(id)target selector:(SEL)sel object:(nullable id)arg;

– (instancetype)initWithInvocation:(NSInvocation *)inv NS_DESIGNATED_INITIALIZER;

@property (readonly, retain) NSInvocation *invocation;

@property (nullable, readonly, retain) id result; // Execution result

Example: 👇

It can’t add multiple executions like NSBlockOperation, so it’s used less often.




4. The use of NSOperationQueue

NSBlockOperation is the only subclass of the system that can add multiple blocks of code to execute, so in real development we’ll have a lot of dependencies between operations, and the class that handles this is NSOperationQueue, which inherits from NSObject!

Its methods and properties:

– (void)addOperation:(NSOperation *)op; // Add an action

– (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait; // Add an array of operations

– (void)addOperationWithBlock:(void (^)(void))block ; // Add a misoperated block

@property (readonly, copy) NSArray<__kindof NSOperation *> *operations; // An array of all operations

@property (readonly) NSUInteger operationCount; // Number of operations

@property NSInteger maxConcurrentOperationCount; // Maximum number of concurrent operations

@property (getter=isSuspended) BOOL suspended; // Whether to pause

@property (nullable, copy) NSString *name; // The queue name

@property NSQualityOfService qualityOfService; // Quality of service

@property (nullable, assign /* actually retain */) dispatch_queue_t underlyingQueue; // Priority queue

– (void)cancelAllOperations; // Cancel all operations

– (void)waitUntilAllOperationsAreFinished; // The method to call when all operations are finished

@property (class, readonly, strong, nullable) NSOperationQueue *currentQueue; // The current queue

@property (class, readonly, strong) NSOperationQueue *mainQueue; / / the home team

Example:





Like the GCD fence effect, both are asynchronous serial effects.