views:

198

answers:

2

I have a "sync" task that relies on several "sub-tasks", which include asynchronous network operations, but which all require access to a single NSManagedObjectContext. Due to the threading requirements of NSManagedObjectContexts, I need every one of these sub-tasks to execute on the same thread. Due to the amount of processing being done in some of these tasks, I need them to be on a background thread.

At the moment, I'm launching a new thread by doing this in my singleton SyncEngine object's -init method:

[self performSelectorInBackground:@selector(initializeSyncThread) withObject:nil];

The -initializeSyncThread method looks like this:

- (void)initializeSyncThread
{
    self.syncThread = [NSThread currentThread];
    self.managedObjectContext = [(MyAppDelegate *)[UIApplication sharedApplication].delegate createManagedObjectContext];
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    [runLoop run];
}

Is this the correct way to start up the NSRunLoop for this thread? Is there a better way to do it? The run loop only needs to handle 'performSelector' sources, and it (and its thread) should be around for the lifetime of the process.

When it comes to setting up an NSAutoreleasePool, should I do this by using Run Loop Observers to create the autorelease pool and drain it after every run-through?

A: 

I'm not 100% sure this is the most efficient way to solve your problem, but I'm doing like this...

Since the asynchronous network operations can take different time to complete (or to timeout) I keep track of them with an instance variable (in this case a BOOL called callComplete)

When the code for firing of the network reqeust is started, and my NSURLConnection has gone away and doing it's magic, I wait for the call to be complete like this.

while(!callComplete && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]){
    // Here you can perform other checks, like making sure the method isn't running forever (with a timeout variable)
    // Just set callComplete to YES when done
}
alleus
A: 

Regarding the NSAutoreleasePool, I simply create one on the start of my selector that is run in the background. Then after the Run Loop is done (and my calls are complete) i release as usual before returning.

alleus
I have 7-8 methods (and may eventually have more) that need an autorelease pool on the background thread. If there's a way to set it up and drain it from the run loop itself (like how CocoaTouch does it for the Main Thread), it would definitely be preferable.
Nick Forge
I think that you can use run loop observers to know when it is done processing an event. For more info, look at Apple docs.
nazgul42