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 (Cocoa-dev@lists.apple.com)

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 arch...@mail-archive.com

Reply via email to