iPhone: NSOperation and Custom Handlers

Now I come from a flex world, so dont hurt me when I say this was a tough thing to figure out for me.  Typically in Flex, you can create handlers fairly easily. Ok, really easily.  For the iPhone, I wanted to basically have the same custom handler “handle” my operation. Hmmm….enter the delegate.

This is a pretty cool technique (fundamental actually) that can be used in your code to “handle” different things throughout your application. So in this exampkle, lets say that you have a UITableViewController that you want to fetch a TON of data.

So I will have two classes I am creating:

- my UITableViewController
- my NSOperation subclass

So here is the code for the NSOperation subclass so you can kind of get a feel for that first.


@interface MyFetchDataOperation : NSOperation
{
// this is our delegate that will handle the results
// of our operation

id   myHandlerDelegate;

}

@property (nonatomic, retain) id     myHandlerDelegate;
@ end
// and here is the .m (implementation file)
// this is just showing the main method override.

@implementation MyFetchDataOperation

@synthesize myHandlerDelegate;
// when subclassing the NSOperation, we simply override the main method
-(void)main
{

// perform my HUGE data fetch here!
......

// on complete of the HUGE data fetch we can now check on the responder and call
// our custom handler!

if( [myHandlerDelegate respondsToSelector:@selector(handleFetchDataOperation:)])
{
[myHandlerDelegate performSelectorOnMainThread:@selector(handleFetchDataOperation:) withObject:myFetchedDataArray waitUntilDone:YES];
}

}

@end

//end

In our subclasses NSOperation you will see the myHandlerDelegate property.  This is what you need to create so that when you instantiate your NSOperation, you can set the myHandlerDelegate to any handling class you want, in this case, it will be our UITableViewController.  Cmon, lets check it out. haha.


@interface MyTableViewController : UITableViewController
{
// we will add our operations to the operationQueue
// to kick them off
NSOperationQueue  *operationQueue;
}
@property (nonatomic, retain) NSOperationQueue  *operationQueue;
@end

@implementation MyTableViewController
@synthesize operationQueue;

-(void)viewDidLoad
{
// init the operationQueue
// in this case I am initializing the operationQueue in my viewController
// but typically you can place this in your AppDelegate, you typically dont need
// a ton of queues!

self.operationQueue = [[NSOperation alloc] init];

}

-(void)fetchMyData
{

MyDataFetchOperation  *fetchOp  = [[MyDataFetchOperation alloc] init];
fetchOp.myHandlerDelegate = self;
[self.operationQueue addOperation:fetchOp];
}
// our custom success handler
// in our operation we are calling a "handleFetchDataOperation" handler, well here it is!

-(void)handleFetchDataOperation:(NSMutableArray *)myFetchedData
{
// handle your complete operation and your data accordingly
}

@end
//end

Now I used to do this with notifications, but well, this seems more proper to me.
any feedback would be cool, and let me know if there is a better way!

Tags: ,

7 Responses to “iPhone: NSOperation and Custom Handlers”

  1. Aral Balkan Says:

    Hey man,

    Unless I’m just not seeing it, the code snippet above is missing the initialization of the NSOperationQueue. Something like:

    operationQueue = [[NSOperationQueue alloc] init];

    Also, there’s a typo on the NSOperationQueue method, it should be addOperation not addObject.

    Thanks for the write-up; good to see other Flashers playing with the iPhone :)

  2. admin Says:

    Ah! Great catch! And yes, you are correct, needs to be iniitalized. Updating the code, and good catch on the addObject. Will fix both! (must have been one late night!)

    Thanks Again

    John

  3. Aral Balkan - Links for 2009-04-21 Says:

    [...] a day in the life » iPhone: NSOperation and Custom Handlers Now I come from a flex world, so dont hurt me when I say this was a tough thing to figure out for me. Typically in Flex, you can create handlers fairly easily. Ok, really easily. For the iPhone, I wanted to basically have the same custom handler “handle” my operation. Hmmm….enter the delegate. (tags: iphone nsoperation nsoperationqueue delegates) [...]

  4. M Tab Says:

    While it’s hard to tell from the context, if you were fetching data from a URL, NSURLConnection would be far more appropriate. Data is returned through delegate methods you implement but you also get some fairly detailed error reporting and the ability to handle redirects to boot. NSOperation would be something that makes more sense for running a set of computations for which you might otherwise use NSThread various synchronization primitives.

  5. Aaron Burghardt Says:

    If your code samples are complete, it appears you have some memory leaks. I think you want:

    self.operationQueue = [[[NSOperation alloc] init] autorelease];

    or follow Aral’s example, then release it in a dealloc. And similarly:

    MyDataFetchOperation *fetchOp = [[[MyDataFetchOperation alloc] init] autorelease];

    or just release it after you add it to the queue.

  6. leeg Says:

    Hi,

    your NSOperationQueue ivar should probably be initialised to an instance of NSOperationQueue, not NSOperation. Still, you’re the one who compiled and ran the code… :-)

  7. admin Says:

    thanks for the comments folks!

    This is a simple sample extracted from my full code, so I apologize for typos and forgetting to write in the initializers. thanks to all for catching the typos!

    My intention in my code was to use NSOperationQueue and NSOperation to fetch data from an sqlite database, and then run intense calculations on that data. So @M Tab, I agree about the NSURLConnection, but in this case, I cant use it. ;-)

    @Aaron – This code sample is most certainly not complete. I am trying to figure out a good way to post all of the files needed. In some cases its quite a few. So for the purposes of blogging I just tried to pull out a simple sample to get some folks started with NSOperation. And yes, I am releasing the operations after they are added to the queue in my project code. Thanks for the post!

    John

Leave a Reply

All Rights Reserved Copyright © 2008 Design by StyleShout and Clazh | Distributed by eBlog Templates