While the application may still run fine with that, there is one big problem: it's blocking the run loop.
With a large call stack, the application could be creating a large amount of autorealeased objects that gobble up memory and won't get released until the application's main thread hits the run loop. I don't foresee such objects being around that long but what if you're in the middle of intense EVE PvP and you suddenly get a deadly lag spike because this app was running in the background and suddenly required a lot of memory? You wouldn't have guess it was this app but that wouldn't change the fact that this app made your EVE experience worse.
The more noticeable problem, though, is that huge call stacks that last several seconds prevent events from being received on the run loop. The application essentially hangs until it finishes its task.
Sometime this weekend, hopefully, I'll be making a pass through some of the code and changing it around to use NSNotifications. I might also post up some diagrams about the logic flow of my code. Its getting complicated to the point where I'm occasionally struggling to keep it all straight in my head.
Oh, and as for the NSManagedObjectContextDidSaveNotification thing you mentioned, Erik, I did some research on it. NSNotifications on a spawned thread never hit the main thread. NSDistributedNotifications are needed for that and I'm not sure I want to go there. A general did save notification might be too broad of a notification, too. For example, updating a character's learned skills table view is done via a notification. If only character A's data changed, there isn't any need to update character B's table view. What I might end up doing is making my set of notifications based on what kind of data gets updated.

Vadim,
ReplyDeleteYou can use NSManagedObjectContextDidSaveNotification in a way that is smart enough to handle only the changed data.
For example (from my admittedly hacked code), here is the registration statement:
// Register to be notified of managed context change
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextDidSave:)
name:NSManagedObjectContextDidSaveNotification object:nil];
and here is the relevant method:
-(void)contextDidSave:(NSNotification*)saveNotification {
// Update the MOC when another context saves changes.
[[self managedObjectContext] performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
withObject:saveNotification
waitUntilDone:YES]; // yes vs. no -- seems to impact mem footprint a lot
return;
}
The mergeChangesFromContextDidSaveNotification is the smart part.
Good luck,
Erik
Boy, I guess I need to figure out how to get code formatting in the commenting system to work...
ReplyDeletemergeChangesFromContextDidSaveNotification: is 10.5 only. Yes, I know my app doesn't work in 10.4 (bindings issues afaik) but its something that I'll try to work on at some point.
ReplyDelete