views:

300

answers:

2

Hi everyone,

I would like to use my custom NSManagedObject like a normal object (as well as its regular functions). Is it possible to modify the class in order to be able to initialize it like a normal object?

[[myManagedObject alloc] init];

Thanks

edit: to clarify the question, will it screw everything up if I change the @dynamic with @synthesize in the implementation?

+2  A: 

The managed object context is a required property of NSManagedObject therefore you can't properly initialize an instance of it without inserting it into a context. It looks at the context to understand it its entity and it notifies the context when any of its properties change.

The @dynamic and @synthesize are just compiler directives. You can switch to @synthesize from @dynamic as long as you provide proper getters and setters yourself. Since NSManagedObject relies heavily on key-value observing to function, you do have to write KVO compliant accessors.

If you need to initialize an NSManagedObject subclass, you override awakeFromInsert which will let you provide customization to the instance when it is created. You can also customized the object every time it is fetched using awakeFromFetch.

TechZen
Thanks... it looks clearer now! What I wanted to do is to use these classes outside my persistent storage (like regular objects); which seems impossible
ncohen
A: 

I do this quite often in one of my apps. My approach is to initialize the object with:

-(id)initWithEntity:(NSEntityDescription *)entity insertIntoManagedObjectContext:(NSManagedObjectContext *)context

passing nil for the context. To get the entity description, you do need access to the managedObjectContext. I tend to get the entity description when my app starts and then store it in an instance variable in my app delegate.

Here's an example:

//inside my "Engine" class
self.tweetEntity = [NSEntityDescription entityForName:@"Tweet" inManagedObjectContext:self.moc];

//later on when I want an NSManagedObject but not in a managed object context
Tweet *tweet = [[[Tweet alloc] initWithEntity:self.engine.tweetEntity insertIntoManagedObjectContext:nil] autorelease];

This allows me to use NSManagedObjects without storing them in a database. Later on, if I decide I do want the object inserted into my database, I can do it by inserting it into my managed object context:

[self.moc insertObject:tweet];
Gotosleep
The problem is that my entity "Element" has a relationship with the entity "Ingredient" and when I try to use your technic, I try to do element.ingredient = anotherElement.ingredient. I get an error: 'Illegal attempt to establish a relationship 'ingredient' between objects in different contexts'
ncohen
If the ingredient is stored in a managed object context, then yeah you will have a problem. If the ingredient is also initialized with initWithEntity, then it should work.
Gotosleep