Core Data Crash on MOC Release
Core Data Crash on MOC Release
- Subject: Core Data Crash on MOC Release
- From: Greg Reichow <email@hidden>
- Date: Thu, 13 Aug 2009 22:51:02 +0800
Long time lurker, first time to post.
I have a iPhone 3.0 application that is using core data in an
NSOperation to perform some updates. It is using it's own
NSManagedObjectContext connected to a common (with the main thread)
persistent store coordinator. Everything works great until the
NSOperation ends and is releasing the managed object context. I get
an EXC_BAD_ACCESS on the operation thread. Here is the trace:
#0 0x91a3c688 in objc_msgSend
#1 0x0036c854 in -[_PFManagedObjectReferenceQueue
_processReferenceQueue:]
#2 0x003a7c40 in -[NSManagedObjectContext(_NSInternalAdditions)
_dispose:]
#3 0x0040c92d in _deallocateContextBackgroundThread
#4 0x0035f41c in minion_duties2
#5 0x96777155 in _pthread_start
#6 0x96777012 in thread_start
At first I had assumed a simple memory management problem. The MOC is
alloc'd by method call from the main method and released in the
dealloc method of the operation. New objects are being inserted into
this MOC & saved (and the main thread MOC being merged) before the
dealloc. One clue is that if no new objects are added, it does not
cause the crash above. So, my guess is that something bad is
happening to the managed objects and they are being over-released?
During the creation of managed objects, at certain intervals a local
autorelease pool is created, then objects saved, then the pool is
drained. Yet, even if the managed objects are released, it does not
seem that the context should crash on it's own release?
I have spent some time searching on google and found another case of
this occurring. Yet, the solution was to set the MOC to retain the
managed objects. This did not work in my case. I have also tried
forcing the MOC to processPendingChanges and also reseting prior to
the release to see if that would help, no luck. Of course,
eliminating the release of the MOC in the dealloc method did keep it
from crashing (and everything works great), but this then becomes a
leak.
Anyone have a similar problem or an idea on how to further figure this
out?
Here is a cut of the code showing the relevant sections.
.h
#import <Foundation/Foundation.h>
@interface GRUpdateDatabaseOperation : NSOperation
{
id delegate;
NSManagedObjectContext *managedObjectContext;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
}
@property (nonatomic, assign) id delegate;
@property (nonatomic, readonly) NSManagedObjectContext
*managedObjectContext;
@property (nonatomic, retain) NSPersistentStoreCoordinator
*persistentStoreCoordinator;
- (id)initWithDelegate:(id)aDelegate persistentStoreCoordinator:
(NSPersistentStoreCoordinator *)aPersistentStoreCoordinator;
@end
.m
#import "GRUpdateDatabaseOperation.h"
@implementation GRUpdateDatabaseOperation
@synthesize delegate;
@synthesize persistentStoreCoordinator;
- (id)initWithDelegate:(id)aDelegate persistentStoreCoordinator:
(NSPersistentStoreCoordinator *)aPersistentStoreCoordinator
{
if (!(self = [super init])) {
return nil;
}
self.delegate:aDelegate;
self.persistentStoreCoordinator = aPersistentStoreCoordinator;
return self;
}
- (void) dealloc
{
[managedObjectContext release]; // problem with crash is here!
[persistentStoreCoordinator release];
[super dealloc];
}
#pragma mark Core Data Stuff
- (NSManagedObjectContext *) managedObjectContext {
if (managedObjectContext != nil) {
return managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator =
self.persistentStoreCoordinator;
if (coordinator != nil) {
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:
coordinator];
[managedObjectContext setUndoManager:nil]; // speeds up performance
for no undo
}
return managedObjectContext;
}
- (void)saveAction:(id)sender {
NSError *error;
if (![[self managedObjectContext] save:&error]) {
// Handle error
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
}
-(void) contextDidSave:(NSNotification *)notification
{
if ([self.delegate respondsToSelector:@selector(mergeChanges:)]) {
DLog(@"Sending off mergeChanges to main thread");
[self.delegate performSelectorOnMainThread:@selector(mergeChanges:)
withObject:notification waitUntilDone:YES];
}
}
#pragma mark Main
- (void)main
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextDidSave:)
name:NSManagedObjectContextDidSaveNotification
object:self.managedObjectContext];
.... BUNCH OF CODE HERE TO CREATE CREATE AND INSERT NEW OBJECTS INTO
MOC ...
[self saveAction:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSManagedObjectContextDidSaveNotification
object:self.managedObjectContext];
}
@end
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden