I would like to develop a kind of template or canonical implementation for a concurrent subclass of NSOperation.Edit: there is a related request which implements the NSOperation subclass in Swift.Requirements:Thread safe API.start shall only start the task once, otherwise it has no effect.The NSOperation object shall be immortal while the task is executing.References:https://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.htmlSolutionSo far, I came up with this solution:#import <Foundation/Foundation.h>/** Canonical, Concurrent Subclass of NSOperation */typedef void (^completion_block_t)(id result);@interface MyOperation : NSOperation// Designated Initializer// For the sake of testing, parameter count equals the duration in 1/10 seconds until the task is fininshed.- (id)initWithCount:(int)count completion:(completion_block_t)completioHandler;@property (nonatomic, readonly) id result;@property (nonatomic, copy) completion_block_t completionHandler;@end@implementation MyOperation {    BOOL _isExecuting;    BOOL _isFinished;    dispatch_queue_t _syncQueue;    int _count;    id _result;    completion_block_t _completionHandler;    id _self;  // immortality}- (id)initWithCount:(int)count completion:(completion_block_t)completionHandler{    self = [super init];    if (self) {        _count = count;        _syncQueue = dispatch_queue_create(op.sync_queue, NULL);        _completionHandler = [completionHandler copy];    }    return self;}- (id) result {    __block id result;    dispatch_sync(_syncQueue, ^{        result = _result;    });    return result;}- (void) start{    dispatch_async(_syncQueue, ^{        if (!self.isCancelled && !_isFinished && !_isExecuting) {            self.isExecuting = YES;            _self = self; // make self immortal for the duration of the task            dispatch_async(dispatch_get_global_queue(0, 0), ^{                // Simulated work load:                int count = _count;                while (count > 0) {                    if (self.isCancelled) {                        break;                    }                    printf(.);                    usleep(100*1000);                    --count;                }                // Set result and terminate                dispatch_async(_syncQueue, ^{                    if (_result == nil && count == 0) {                        _result = @OK;                    }                    [self terminate];                });            });        }    });}- (void) terminate {    self.isExecuting = NO;    self.isFinished = YES;    completion_block_t completionHandler = _completionHandler;    _completionHandler = nil;    id result = _result;    _self = nil;    if (completionHandler) {        dispatch_async(dispatch_get_global_queue(0, 0), ^{            completionHandler(result);        });    }}- (BOOL) isConcurrent {    return YES;}- (BOOL) isExecuting {    return _isExecuting;}- (void) setIsExecuting:(BOOL)isExecuting {    if (_isExecuting != isExecuting) {        [self willChangeValueForKey:@isExecuting];        _isExecuting = isExecuting;        [self didChangeValueForKey:@isExecuting];    }}- (BOOL) isFinished {    return _isFinished;}- (void) setIsFinished:(BOOL)isFinished {    if (_isFinished != isFinished) {        [self willChangeValueForKey:@isFinished];        _isFinished = isFinished;        [self didChangeValueForKey:@isFinished];    }}- (void) cancel {    dispatch_async(_syncQueue, ^{        if (_result == nil) {            NSLog(@Operation cancelled);            [super cancel];            _result = [[NSError alloc] initWithDomain:@MyOperation                                                 code:-1000                                             userInfo:@{NSLocalizedDescriptionKey: @cancelled}];        }    });}@end
Canonical Implementation of a Subclass of NSOperation
objective c;ios;osx