Why is the +initialize method of Core Data managed objects being called twice?

core-data, objective-c

Solution

The accessor methods for Core Data properties are dynamically created at runtime. This works by creating a subclass `MyClass_MyClass_` (of `MyClass`) and adding the necessary methods to the subclass.

Core Data also does some tricks to hide the fact that that the objects of your entity are actually instances of the subclass:

e = [NSEntityDescription insertNewObjectForEntityForName:@"MyClass" inManagedObjectContext:context];
NSLog(@"%@", [e class]);               // --> MyClass
NSLog(@"%s", object_getClassName(e));  // --> MyClass_MyClass_

Perhaps it becomes even more obvious if you don't set a custom class for your entity. In that case the output is

NSLog(@"%@", [e class]);               // --> NSManagedObject
NSLog(@"%s", object_getClassName(e));  // --> NSManagedObject_MyClass_

So `e` "looks like" an instance of `NSManagedObject`, but is indeed an instance of a dynamically created subclass `NSManagedObject_<EntityName>_`. This subclass implements all the accessor methods (which are unique to this entity).

Problem

I have a managed core data object with a `+initialize` method. (If it matters, I am looking to use that method to initialize a static variable that is expensive to to set up.) While testing that initialization code I was surprised to discover that the `+initialize` method is getting called twice. The first time `initialize` is being called `self` is defined as `(Class) MyClass`, as I would expect. The second time `initialize` is being called `self` is defined as `(Class) MyClass_MyClass_`, which leads me to suspect some sort of unusual initialization for Core Data managed objects. While this doesn't pose a problem for me (I can just test to see if the static variable has already been initialized, which I would do anyway, to handle ubclassing), it makes me suspect that Core Data is doing something in the object or class lifecycle that I don't understand. Can someone explain to me what is going on in this `MyClass_MyClass_` `+initialize` method invocation?

Original source