Re: core-data crash on save. [SOLVED]
Re: core-data crash on save. [SOLVED]
- Subject: Re: core-data crash on save. [SOLVED]
- From: John Clayton <email@hidden>
- Date: Thu, 20 Nov 2008 00:20:17 +0100
For all that answered me - a huge thanks. I've solved my particular
flavour of this problem now.
Partly, its a problem of the documentation - and partly my particular
configuration. Here, for future reference at the 'facts' I collected
along my learning experience - which led me finally to a solution.
My particular gotchas were:
- performing a fetch during the
initWithEntity:insertIntoManagedObjectContext: (caused a crash after
deleteObject:)
- I have set the undo manager to nil in the context, because I want to
control it, this has the side effect that processPendingChanges does
NOT get called at the end of the event loop (even if you explicitly
set it to do so in the context).
1. a standard 10.5 core-data project includes undo support - which
implies (not obviously) that processPendingChanges gets called at the
end of the event loop automatically.
2. processPendingChanges is responsible for deleting objects that you
nuked with [context deleteObject:] - and this method will only be
called if you actually have an undo manager in your core data
context. (I dont - I explicitly disabled it because I don't want such
a fine grained, uncontrollable core-data undo architecture - thats
another story for another time though)
3. during the following methods, one should NEVER modify the state of
the data-model - from the docs:
Methods to Override Considerations
The following methods are intended to be fine grained and not
perform
large scale operations. You must not fetch or save in these
methods. In
particular, they should not have side effects on the managed object
context:
� initWithEntity:insertIntoManagedObjectContext:
� didTurnIntoFault
� dealloc
now, I *was* indirectly performing a fetch within the my
awakeFromInsert method - and that's bad, because awakeFromInsert is
called from within initWithEntity:insertIntoManagedContext: ... and
processPendingChanges can get/fetch as well, so the golden rule there
is easy: don't fetch, dont cause processPendingChanges: to be called
during the above three methods.
4. if doing some entirely non-user-initiated mods to the core-data
layer (i.e. from a sep thread), then the objects must be (a) added
into the core data context on the main thread, (b) you must call
processPendingChanges on the context to apply the changes.
Point (4) didn't apply to me as I'm not doing any off-UI-thread work,
but its worth adding to the list.
---------------------
So, lots of 'issuettes' with my code there. Now I understand why it
crashed, why my initial solutions failed, why refactoring it has
worked and most importantly, how I can continue / move forward.
So all in all, success - my hat goes off to the people that took the
time to answer me - thank you.
--
John Clayton
Skype: johncclayton
On 19/11/2008, at 12:43 AM, Quincey Morris wrote:
On Nov 18, 2008, at 13:53, John Clayton wrote:
So, with the extra two bits of knowledge, namely:
- I have a Nullify relationship from Effect to the Layers 'effects'
set/relationship
- it works if I call processPendingChanges
does it still 'reek' to you of something being broken?
I'm a bit lost as to why I must call processPendingChanges to have
my object deleted immediately. It really does feel like I've
screwed *something*, *somewhere*. I thought the objects that I
delete would really be deleted at the end of the event loop?
If you'll excuse a short rant ...
I think there's a semantic issue here, about what "deletion" means
in Core Data. AFAIK, it's not referring to the lifetime of the
object in your (in-memory) object graph, but the lifetime of the
Core Data entity instance in your persistent store. If I am correct,
deleting an object is "really" just an instruction to omit the
object from the persistent store the next time it's saved.
In those terms, it's not entirely surprising that the effect of
"deleteObject" might be deferred from the moment you call it to some
later time (processPendingChanges, or save, or whatever). The actual
object doesn't get deleted by "deleteObject", only its persistence
in the store. The object gets *deallocated* when there are no
references to it (regardless of whether it's deleted in the store or
not).
I would have expected the delete rule to be applied at
"deleteObject" time, but it seems not completely illogical to do it
later. (Part of the reason for processPendingChanges is, I believe,
to avoid tracking a lot of redundant individual changes in the undo
manager, and that's a Good Thing.)
It might be worthwhile filing a bug on this, saying that the delete
rule ought to be applied at a predictable time, or that the
documentation should be updated to make it clear *when* it's done.
In practical terms, I'm suggesting you continue with your A/B
methodology:
[effect retain];
effect.layer = nil; // let Core Data do the work for the inverse
[moc deleteObject: effect];
[effect release];
I don't think this reeks of something broken, it just reflects a
piece of complexity in Core Data's semantics: there really are 2
things you need to do -- one piece of object graph management and
one piece of persistent store management.
If it still crashes, then I would investigate the issue as a memory
management problem first.
_______________________________________________
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:
@mac.com
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