I'm fetching some data from Facebook Connect (using the FBConnect Objective-C 2.0 framework) and I'm doing all that in an NSOperation. It is in an NSOperation because I have several other operations that run as well and this is one of them.
The problem is that all the FBConnect calls are asynchronous. Because of this, the main method of the NSOperation quickly finishes and the operation is marked as completed.
Is there some way to overcome this? It would appear there are no synchronous options in FBConnect!
Many thanks,
Mike
Asynchronous operations allow executing long-running tasks without having to block the calling thread until the execution completes. It's a great way to create separation of concern, especially in combination with creating dependencies in-between operations.
An abstract class that represents the code and data associated with a single task.
GCD is a low-level C-based API that enables very simple use of a task-based concurrency model. NSOperation and NSOperationQueue are Objective-C classes that do a similar thing. NSOperation was introduced first, but as of 10.5 and iOS 2, NSOperationQueue and friends are internally implemented using GCD .
A queue that regulates the execution of operations.
Below is a full example. In your subclass, after your async method completes, call [self completeOperation]
to transition to the finished state.
@interface AsynchronousOperation() // 'executing' and 'finished' exist in NSOperation, but are readonly @property (atomic, assign) BOOL _executing; @property (atomic, assign) BOOL _finished; @end @implementation AsynchronousOperation - (void) start; { if ([self isCancelled]) { // Move the operation to the finished state if it is canceled. [self willChangeValueForKey:@"isFinished"]; self._finished = YES; [self didChangeValueForKey:@"isFinished"]; return; } // If the operation is not canceled, begin executing the task. [self willChangeValueForKey:@"isExecuting"]; [NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil]; self._executing = YES; [self didChangeValueForKey:@"isExecuting"]; } - (void) main; { if ([self isCancelled]) { return; } } - (BOOL) isAsynchronous; { return YES; } - (BOOL)isExecuting { return self._executing; } - (BOOL)isFinished { return self._finished; } - (void)completeOperation { [self willChangeValueForKey:@"isFinished"]; [self willChangeValueForKey:@"isExecuting"]; self._executing = NO; self._finished = YES; [self didChangeValueForKey:@"isExecuting"]; [self didChangeValueForKey:@"isFinished"]; } @end
put your FBConnect
calls in 'start
', not 'main
', and manage the 'isFinished
' 'isExecuting
' properties. (and return YES
for 'isConcurrent
')
For more details, see Apple's documentation on writing concurrent NSOperations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With