Re: Core Data Crash on MOC Release
Re: Core Data Crash on MOC Release
- Subject: Re: Core Data Crash on MOC Release
- From: Volker in Lists <email@hidden>
- Date: Thu, 13 Aug 2009 19:03:50 +0200
Hi,
do you have any observers or such on objects inside the moc (speak on
entities)? I had a hard to trace down crash similar to yours and in my
case I just needed some cleanup work on -didTurnToFault for the
entity. Are there relationships established and not "destroyed" again
completely. Again -didTurnToFault may be a good place to clean up some
stuff.
As a side note:
Why don't you call
self.persistentStoreCoordinator = nil;
instead of releasing the persistentStoreCoordinator ?
self.delegate = nil; could also be useful - I had bad experiences by
the delegate retaining my object... and setting it to nil helped there
as well.
Cheers,
Volker
Am 13.08.2009 um 16:51 schrieb Greg Reichow:
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
_______________________________________________
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