The tricky bit of managed object memory comes when the objects are turned into faults. A fault is a ghost of the object. It exists and responds to messages but it doesn't have it's attributes populated. For example, you can count the number of objects in a to-many relationship even if the objects themselves are faults.
Faults are used to maintain the object graph in memory without the overhead of the actual data. The object is still technically alive so its dealloc has never been called.
When the context turns an object into a fault, the object releases and nils it's attributes in memory. It does this in willTurnIntoFault
and didTurnIntoFault
. If you need to do some special releasing you should override those methods (usually the latter.)
Faulting makes managed objects rely on different methods than other classes for intialization and clean up. You intialize in awakeFromInsert
or awakeFromFetch
and you dealloc in willTurnIntoFault
and didTurnIntoFault
.
It's important to follow the rules for managed objects because the context might keep thousands of faulted objects in memory. If you create a custom attribute but do not release it when the object becomes a fault, then you could easily tie up a large amount of memory accidentally.