When implementing this method:
-createDestinationInstancesForSourceInstance:entityMapping:manager:error:
in a subclass of NSEntityMigrationPolicy, one typically loops through
attributes of the given source instance, does whatever migration logic is
desired, and then sets the results as attributes of a new destination instance.
Some time ago, I learned that one does not want to invoke the -foo and setFoo:
accessors in this method, because, duh, the invoked methods may no longer exist
in the current implementation of the managed object. Life has improved since
I've been careful to leave the objects typed as unsubclassed NSManagedObject
instances, which forces me to use -valueForKey: and -setValue:forKey:.
But wait, there's more. Although these source objects log their type as Baz or
whatever, they do not respond to Baz subclass methods, only NSManagedObject
methods. They are like the proxy objects that are sometimes delivered by KVO.
It's rather confusing to see an exception such as "-[Baz foo]: unrecognized
selector" when your implementation of Baz clearly has a -foo, but it makes
sense when you stop to consider what's going on. Migration is sandboxxed. The
system only has the old store to work with; not the old class. Because the
entity and apparently the class are stored in the store, it knows that the
object is a Baz instance, but it does not know any of the old Baz behaviors.
The implication of this is that even -valueForKey: and -setValue:forKey: will
fail if the -foo or -setFoo: accessors (which the system runs in their stead)
have been overridden to perform business logic which invoke other subclass
methods. "Unrecognized selector" exceptions are raised when these other
subclass methods are invoked.
Now, one does not generally want an app's regular business logic to be run
during a migration anyhow; any business logic should be implemented within the
migration sandbox. Therefore, it seems that, as a general rule, in
-createDestinationInstancesForSourceInstance::::, one should access properties
only via the primitive accessors -primitiveValueForKey: and
-setPrimitiveValue:forKey:.
At least I seem to have solved this morning's little programming challenge by
adding "Primitive" to the accessors which were raising exceptions.
Should I go through all of my -createDestinationInstancesForSourceInstance::::
implementations and change all accessors to the primitive accessors? I can't
find any discussion of the lameness of the source instances in the Core Data
Model Versioning and Data Migration Programming Guide, and the phrase
"Primitive" does not even appear in that document.
Thanks,
Jerry Krinock
_______________________________________________
Cocoa-dev mailing list ([email protected])
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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]