Custom Initializer for an NSManagedObject

According to the docs:

You do not have to override init. You are not recommended to override initWithEntity: insertIntoManagedObjectContext:

and instead you should use awakeFromInsert or awakeFromFetch.

It’s normal if all I want to do is set some attribute to the current one or similar, but what if I want to send another object and set the attributes based on its information?

For example, in a subclass of NSManagedObject called "Item", I need the thing initFromOtherThing: (Thing *), in which the element name is given for the object. I would like to avoid "just remembering" to set the name every time immediately after creating the item and update fifteen different controller classes when I decide that I want Item to also set a different default attribute based on Thing. These are actions tied to a model.

How should I handle this?

+2
source share
1 answer

I think the best way to handle this is to subclass NSManagedObject, and then create a category to store what you want to add to the object. For example, several class methods for a unique and convenient creation:

+ (item *) findItemRelatedToOtherThing: (Thing *) existingThing inManagedObjectContext *) context {
    item *foundItem = nil;
    // Do NSFetchRequest to see if this item already exists...
    return foundItem;
}

+ (item *) itemWithOtherThing: (Thing *) existingThing inContext: (NSManagedObjectContext *) context {
    item *theItem;
    if( !(theItem = [self findItemRelatedToOtherThing: existingThing inManagedObjectContext: context]) ) {
        NSLog( @"Creating a new item for Thing %@", existingThing );
        theItem = [NSEntityDescription insertNewObjectForEntityForName: @"item" inManagedObjectContext: context];
        theItem.whateverYouWant = existingThing.whateverItHas;
    }
    return theItem; 
}

initWithEntity:insertIntoManagedObjectContext: , , :

item *newItem = [item itemWithOtherThing: oldThing inContext: currentContext];
+1

All Articles