views:

52

answers:

2

I created my own class that I want Core Data to use instead of NSManagedObject:

@interface MyManagedObject: NSManagedObject {
  id delegate;
}

I can't use a category since this declares an ivar. All of my Core Data objects use concrete classes rather than being instances of NSManagedObject. I use the code generator to generate these files. Here's an example of what a Contact object might look like:

@interface Contact: NSManagedObject {
}

I know that I can manually change NSManagedObject to MyManagedObject in this generated code, but I will need to do this every time I regenerate the code. Is there any way to make it automatically use my own class?

Additionally, the #import in any solution might be a problem. Ideally I want it to use @class MyManagedObject rather than #import "MyManagedObject.h", since MyManagedObject.h is located in a library and the header needs a folder prefix to be accessible (e.g. #import "MyLib/MyManagedObject.h").


I tried creating a dummy object in the .xcdatamodel file with the same name and specifying that all objects inherit from it, but there are two problems. The first is that it is using #import "MyManagedObject.h", which it can't find due to the reason I specified above. The second problem is that I'm not sure it's a good idea to fool Core Data into thinking the class is inheriting from another Core Data object... even if I'm not generating the code file. I'm guessing that Core Data might be doing some unnecessary things behind the scenes because it believes there is an extra class which my classes are inheriting from.

I guess I can solve the first problem using another layer of classes. For example, I would specify that the objects inherit from MyProjectManagedObject and create a MyProjectManagedObject.h file in my project:

#import "MyLib/MyManagedObject.h"

@interface MyProjectManagedObject: MyManagedObject {
}

... and now my auto generated files will look like this:

#import "MyProjectManagedObject.h"

@interface Contact: MyProjectManagedObject {
}

... which will work. The only problem is the second one I mentioned above about extra code running behind the scenes in Core Data. Is this something to worry about or should I ignore it? Are there any other ways to do this which solve both problems mentioned above?

A: 

Don't use inheritance in your data model if you're using the SQL backend. Because of the implementation of the SQL backend, it has horrible performance and space characteristics. (This is Apple's recommendation.)

I may be wrong (I'll double-check), but I think you can do what you want using just the class and header files, without messing with the data model. (This is assuming you don't want to actually store your ivar in the data backend.) Just implement MyManagedObject like you did, and make your subclasses inherent from MyManagedObject instead of NSManagedObject (e.g. Contact : MyManagedObject). Note that you only have to do this in the header files, and not the actual data model. The compiler should figure out the rest.

eman
Do you have a link to that recommendation by Apple? Also, the ivar does not need to be in the backend. That's exactly what I originally did, I modified the `.h` file to make it inherit from the correct class. It's just annoying to have to do this every time I regenerate the .h file (i.e. every time the model is changed). That's why I was looking for some other solution.
Senseful
The recommendation is in the "Working With Core Data" developer video (https://deimos.apple.com/WebObjects/Core.woa/BrowsePrivately/adc.apple.com.3391495696.03391495702)
eman
+1  A: 

Take a look at MOGenerator. It'll help with the regenerating the managed object class files at least: it makes you two files for each one. one that you edit and one that is automatically generated. When you regenerate the latter, the former is untouched.

http://digitalflapjack.com/blog/2010/mar/26/mogeneratorftw/

Amorya
This works if you use the `--base MyManagedObject` command line argument.
Senseful