Re: Crashing resetting or releasing an NSManagedObjectContext
Re: Crashing resetting or releasing an NSManagedObjectContext
- Subject: Re: Crashing resetting or releasing an NSManagedObjectContext
- From: Daniel Kennett <email@hidden>
- Date: Fri, 1 May 2009 09:24:34 +0100
Good morning all,
Thanks for your reply. Yes, I have code that triggers relationship
faults, and removing that code solves the problem. However, I need
that code to work! :-)
When fetching the data from the object tree, I call a method on the
pet instance called -pertinentActions. This method loops through
various relationships, calling -pertinentAction on each child object.
I've ruled out the -pertinentAction method, since calling -className
on the child objects also causes the crash to happen. I've also double
and triple checked my retains and (auto)releases and they're all
balanced.
Here's the code that triggers the crash:
-(NSArray *)pertinentActions {
NSMutableArray *actions = [[NSMutableArray alloc] init];
[actions addObject:[self birthdayAction]];
for (InsurancePolicy *policy in [self insurancePolicies]) {
KNClarusPertinentAction *action = [policy pertinentAction];
if (action) {
[actions addObject:action];
}
}
// If I return here, the later crash doesn't happen!
for (VetVisit *visit in [self vetVisits]) {
[visit className];
}
// Returning just after this...
for (Medication *medication in [self medications]) {
[medication className];
}
// ... or this causes the later crash.
return [actions autorelease];
}
Commenting out the for (VetVisit* and for (Medication* loops fixes the
crash. At this point, I'm doing no memory management at all - the -
pertinentActions method is being called thusly:
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];
Pet *pet = [KNClarusQuickDocumentParser petAtURL:url inContext:context];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:[[[pet valueForKey:@"name"] copy] autorelease]
forKey:@"name"];
[dict setValue:[[[pet valueForKey:@"birthday"] copy] autorelease]
forKey:@"birthday"];
// More copying of strings and dates
[..]
[dict setValue:[[[pet valueForKey:@"pertinentActions"] copy]
autorelease] forKey:@"pertinentActions"]; // <--- Here
[context release];
return [dict autorelease];
I think I've stumbled upon a problem with the way I've set up my
model. The insurance policy collection, which doesn't crash after
being accessed, is simply a one-to-many relationship from pet.
However, the Medication and VetVisit relationships are a little more
complex. It goes:
Pet -> Medication(s) -> Medication Course(s) -> Medication Dose(s)
Pet -> Vet Visit(s)
The Medication Dose entity has an optional relationship to Vet Visit
in case the dose was given at a visit to the vet. Here's a screenshot
of that part of my model:
http://www.kennettnet.co.uk/stuff/ClarusModel.png
Right now, I'm at a dead-end. I've ruled out my memory management, and
can't see how I can work around what's happening, or what I'm doing
wrong!
Thanks,
-- Daniel
_______________________
email@hidden
http://www.kennettnet.co.uk
Please include previous messages in any reply you send.
Does the "Pet" class, or any class it has a relationship with,
release or autorelease any "VetVisit" object? I am assuming that the
"Pet" entity has a relationship to "VetVisit"--do you have any code
that would cause the relationship fault to fire? If so, what happens
when you comment that out?
On 29 Apr 2009, at 16:32, Alexander Spohr wrote:
Daniel,
You are trying to fetch an object and keep it - but you want to
ignore / throw away the NSManagedObjectContext. This will never
work. The NSManagedObjectContext keeps the object. Your Pet can
not exist without its NSManagedObjectContext.
You should let the caller provide a NSManagedObjectContext and
fetch your Pet into that context. Make it the callers
responsibility to get a NSManagedObjectContext not yours.
+ (Pet *)petAtURL:(NSURL *)url inContext:(NSManagedObjectContext
*)aManagedObjectContext
Or copy the pet into something like an NSDictionary and return that.
atze
Am 29.04.2009 um 10:59 schrieb Daniel Kennett:
Hi list,
I'm hoping you guys can help me. I'm loading up a Core Data
store, copying some data out and attempting to clear it all up. I
use this code for my Quicklook plugin, and in parts of my app for
previewing documents in a more advanced manner than Quicklook
provides.
This is how I set up my ManagedObjectContext:
+(Pet *)petAtURL:(NSURL *)url {
NSManagedObjectModel *managedObjectModel =
[KNClarusQuickDocumentParser managedObjectModel];
NSPersistentStoreCoordinator *coordinator =
[[[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:managedObjectModel] autorelease];
[coordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:url
options:nil
error:&error];
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc]
init];
// ^ Not Autoreleasing here. It's the responsibility of the
caller to release the MOC. Autoreleasing causes crashes.
[moc setPersistentStoreCoordinator:coordinator];
[[moc undoManager] disableUndoRegistration];
NSError *fetchError = nil;
NSArray *fetchResults;
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init]
autorelease];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"Pet"
inManagedObjectContext:moc];
[fetchRequest setEntity:entity];
fetchResults = [moc executeFetchRequest:fetchRequest
error:&fetchError];
if ((fetchResults != nil) && ([fetchResults count] == 1) &&
(fetchError == nil))
{
NSManagedObject *pet = [[fetchResults objectAtIndex:0] retain];
return [pet autorelease];
}
return nil;
}
And this is how I get the data out and release it:
Pet *pet = [KNClarusQuickDocumentParser petAtURL:url];
// Copy out some data.
NSManagedObjectContext *context = [pet managedObjectContext];
if (context) {
[context reset]; // This call results in EXC_BAD_ACCESS
[context setPersistentStoreCoordinator:nil];
[context release];
}
return [dict autorelease];
-------- End code --------
Different combinations of trying to do this right result in
crashes at different points. Leaving out [context reset] and just
releasing it obviously gives EXC_BAD_ACCESS again. Autoreleasing
the MOC in +petAtURL: causes crashes when the autorelease pool
pops. The only way I can get it to not crash is to -init the MOC
and never release or autorelease it, but that's causing memory
leaks!
Is there a good example anywhere of how to set up and tear down a
Core Data document correctly?
Thanks,
-- Daniel
_______________________
email@hidden
http://www.kennettnet.co.uk
Please include previous messages in any reply you send.
_______________________________________________
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
Keary Suska
Esoteritech, Inc.
"Demystifying technology for your home or business"
_______________________________________________
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