How to properly delete a "temporary" NSManagedObject upon the application quitting
I create a temporary NSManagedObject and associate it with the main NSManagedObjectContext. I need be able to treat it as a fully functioning object (perform fetch requests, etc) inside the context and thus cannot create it without an associated context. I include logic to delete the managed object in ViewWillDisappear under the condition that a new view controller was not just pushed onto the stack:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
// View is disappearing because a new view controller was pushed onto the stack
} else {
// View is disappearing for some other reason
[self.community.managedObjectContext deleteObject:self.community];
}
}
This seems to properly delete the managed object in all cases except for the application quitting. I tried deleting the object in viewDidUnload but it seems the method is not called upon the application quitting. I have considered creating a second managed object context, but want to avoid 开发者_如何学Cthe major overhead if possible.
Thanks, Graham
Keep the managed object in a shared instance of as a class variable so it is reachable from more places in your application then the class you handle it from.
There are two scenarios:
1) before iOS 4.0
When the applicationWillTerminate you can delete the object from the context.
2) Since iOS 4.0.
When your application will go in the background and you will kill the process (the hard way, with the 'kill app bar'), the applicationWillTerminate will never get called. You cannot recognize this event. So your screwed with the applicationWillTerminate.
You will have to solve it like this:
- applicationWillEnterBackground: -> save an identifier to the managed object in the userdefaults or a simple file.
- applicationDidFinishLaunching: -> if file exists, delete the managed object it is referring to.
- applcationWillEnterForeground: -> delete the file.
Now when your app goes into background and comes back, you will have the same state and the object will not be deleted. When you kill your app, the object will be deleted on startup.
In your app delegate, implement the -applicationWillTerminate: method. This method is called right before your application is purged from memory and you can delete the temporary managed object there.
I understand you already have a working answer, but if your object is truly temporary, and will never be saved, why not just create it in a child context? It will still have all the fetch visibility you desire, but will never get pushed to the other contexts, nor saved in the physical database until you call save on the context.
If you never call save, the temporary object will never be saved, thus truly making it temporary.
And the kicker... you don't have to write any extra code at all or handle all the "exiting" conditions since it never got put into the actual database.
applicationWillTerminate
and its multi-tasking cousins work, but since you are only deleting a single object the best way is to save your context after every delete.
Just call - (BOOL)save:(NSError **)error
:
[self.community.managedObjectContext deleteObject:self.community];
NSError *error = nil;
[self.community.managedObjectContext save:&error];
精彩评论