An alternative to the protocol delegate pattern is the termination block. For example, in some random NSURLConnection operation NSURLConnection I define a typedef termination block (just to simplify the syntax of the block later) that returns an NSData if successful, or NSError if not:
typedef void(^CustomOperationCompletionBlock)(NSData *data, NSError *error);
Then I can define a block property for my NSOperation subclass, for example:
@property (nonatomic, copy) CustomOperationCompletionBlock successFailureBlock;
I will often have the execution of my init method of my operation, which will allow me to set this completion block during the init process (in addition to everything I want to initialize):
- (instancetype)initWithURL:(NSURL *)url successFailureBlock:(CustomOperationCompletionBlock)successFailureBlock;
My various methods that handle errors and / or success in my operation then call this completion block to pass the data back:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { if (self.successFailureBlock) {
And, to use this operation with a custom completion block handler, when I start my operation, I can just pass it a custom completion block. For example, it saves data if successful or logs an error if not:
CustomOperation *operation = [[CustomOperation alloc] initWithURL:url successFailureBlock:^(NSData *data, NSError *error) { if (error) NSLog(@"CustomOperation error: %@", error); else [data writeToFile:path atomically:YES]; }]; [queue addOperation:operation];
Obviously, you would modify the typedef block to pass all the objects that make sense to your operation. But this illustrates the basic block mechanism template for a subclass of NSOperation to return data.
Rob Oct. 15 '13 at 6:25 2013-10-15 06:25
source share