I am working on my first core data iPhone application. I am using a navigation controller, and the root view controller displays 4 rows. Clicking the first row takes me to a second table view controller. However, when I click the back button, repeat the row tap, click the back button again, and tap the row a third time, I get an error. I have been researching this for a week with no success.
I can reproduce the error easily:
- Create a new Navigation-based Application, use Core Data for storage, call it MyTest which creates MyTestAppDelegate and RootViewController.
- Add new UIViewController subclass, with UITableViewController and xib, call it ListViewController.
- Copy code from RootViewController.h and .m to ListViewController.h and .m., changing the file names appropriately. To simplify the code, I removed the trailing “_” from all variables.
- In RootViewController, I added #import ListViewController.h, set up an array to display 4 rows and navigate to ListViewController when clicking the first row.
In ListViewController.m, I added #import MyTestAppDelegate.h” and the following code:
- (void)viewDidLoad {
[super viewDidLoad];
if (managedObjectContext == nil) {
managedObjectContext = [(MyTestAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
..
}
The sequence that causes the error is tap row, return, tap row, return, tap row -> error. managedObjectContext is synthesized for the third time. I appreciate your patience and your help, as this makes no sense to me.
ADDENDUM: I may have a partial solution. http://www.iphonedevsdk.com/forum/iphone-sdk-development/41688-accessing-app开发者_Python百科-delegates-managed-object-context.html
If I do not release the managedObjectContext in the .m file, the error goes away. Is that ok or will that cause me issues?
- (void)dealloc {
[fetchedResultsController release];
// [managedObjectContext release];
[super dealloc];
}
ADDENDUM 2: See solution below. Sorry for the formatting issues - this was my first post.
I think I have the answer.
In the default Core Data Navigation Controller template, the AppDelegate does the following:
- (void)awakeFromNib {
RootViewController *rootViewController = (RootViewController *)[navigationController topViewController];
rootViewController.managedObjectContext = self.managedObjectContext;
}
and the RootViewController has the following code:
@interface PractitionerAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
UINavigationController *navigationController;
@private
NSManagedObjectContext *managedObjectContext_;
NSManagedObjectModel *managedObjectModel_;
NSPersistentStoreCoordinator *persistentStoreCoordinator_;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (NSString *)applicationDocumentsDirectory;
@end
plus
- (void)dealloc {
[managedObjectContext_ release];
[managedObjectModel_ release];
[persistentStoreCoordinator_ release];
[navigationController release];
[window release];
[super dealloc];
}
In other words, when the managedObjectContext is set by code, either as above or in the tableView: didSelectRowAtIndexPath, then it needs to be deallocated.
On the other hand, if the managedObjectContext is not passed to the View Controller directly, and the following code is used to set the managedObjectContext...
if (managedObjectContext_ == nil) {
managedObjectContext_ = [(PractitionerAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
... then the managedObjectContext should not be released.
A much shorter answer is here. http://stackoverflow.com/questions/4028797/why-dont-i-have-to-release-managedobjectcontext-in-the-2nd-tableviewcontroller Apparently, even though the MOC is allocated in the View Controller, that has no effect since the MOC is owned by the AppDelegate.
精彩评论