Re: Core Data: During Migration, should use Primitive Accessors only?
Re: Core Data: During Migration, should use Primitive Accessors only?
- Subject: Re: Core Data: During Migration, should use Primitive Accessors only?
- From: Adam Swift <email@hidden>
- Date: Tue, 16 Nov 2010 09:48:42 -0800
On Nov 12, 2010, at 10:51 AM, Jerry Krinock wrote:
> 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.
>
That the objects will be fetched as NSManagedObjects is documented in the versioning & migration guide here Three-Stage Migration. You should be able to use the standard KVC accessors during migration, NSManagedObjects will respond to the foo/setFoo: accessors for properties defined in your managed object model - the accessors will perform better than valueForKey/setValue:forKey: (see Dynamically-Generated Accessor Methods)
> Thanks,
>
> Jerry Krinock
>
> _______________________________________________
>
> 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
_______________________________________________
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