I’ve been having the damnedest time with a Core Data object that has, as one of its properties, a custom class that’s transformable. Behind the scenes, this saves any object as NSData — all you have to do is implement NSCoding. The glitch?
I kept saving, and saving, and saving, and while the initial creation of the objects was persisted just perfectly, any changes I made vanished with a restart of the app. Why could this be? After tearing my hair out, I found this on CocoaBuilder:
Core data attributes are expected to be immutable and will be treated as such. To property track changes to the value of an attribute you’ll need to replace the attribute object on the owning managed object with a different instance.
Translated? That means your ManagedObjectContext and PersistentStoreCoordinator are just looking at your transformable object, seeing that it object A is object A, regardless of whether A.someInterestingProperty used to be set to @”pinkGloves” and now is set to @”beigeGloves”. CoreData is like a bad boyfriend. What haircut? You look fine, sweetie pie. You look great in everything.
So, what do you need to do to make your lazy, good for nothing (just kidding!) Core Data get up off the couch and persist your transformable changes? Just give it what every bad boyfriend wants: give it a clone. Implement NSCopying, and, if you’ve got a somewhat mutable transformable property, implement a method in your NSManagedObject subclass like this:
-(void)refreshTransformable {
id tempTransformable = [self.someTransformableProperty copy];
self.someTransformableCopy = tempTransformable;
[tempTransformable release];
}
A few things to note here:
1. You’ll need to implement NSCopying’s -(id)copyWIthZone in your transformable subclass.
2. Notice I released my tempTransformable. Copy means you own the memory.
3. Remember how I said you own the memory with Copy? That means you shouldn’t autorelease your copy of the object when you implement copyWithZone. Right? Right.
Now kick back, relax like Core Data, and have a brew ski on the couch. You’ve earned it.