Вопрос

I would like to add attributes programmatically to an entity during runtime of my app.

Is this something you would recommend doing or can this lead to issues?

How would I need to combine NSAttributeDescription and NSEntityDescription? I am familiar with creating models using Xcode, but did not do it using NSEntityDescription yet.

Это было полезно?

Решение

It's theoretically possible, but doesn't appear very practical.

You can modify the NSManagedObjectModel programmatically, as well as NSEntityDescription. Note that -setEntities: (NSManagedObjectModel) and -setProperties: (NSEntityDescription) both trigger exceptions if you modify a model that has been instantiated. So you can't modify your existing model's structure. You'd have to create a new one and copy all of your data from the old Core Data stack to the new one based on your new model..

Using NSMutableDictionary is a much saner approach.

Другие советы

This is an article talking about this in great detail. Hope it helps.

I would not do this. If the store becomes incompatible with your model it will just crash. Is this risk really worth the benefit you are trying to create?

I have found that it makes sense to create more (even many more) attributes upfront just "to be on the safe side". The overhead of unused attributes is really minimal, but you get the flexibility of easily adding information to your objects "on the fly".

As pointed out in the comments, one good way to implement that is using a separate entity for attributes and adding them as to-many relationships.

I just used nearly the same technique here: EPPZQueuedObject.h

Although, I think mutate the entity architecture during runtime could lead to incompatiblity issues (an exception actually), when the stored SQLite data won't fit for your initial entities at startup.

So this generic object EPPZQueuedObject is an object of two attributes at all, so I had no intention to use a separate model file only for this purpose. But this structure is not mutating during runtime.

@implementation EPPZQueuedObject


@dynamic creationDate;
@dynamic archivedObject;


+(NSEntityDescription*)entityDescription
{
    //Describe EPPZQueuedObject.
    NSEntityDescription *entityDescription = [NSEntityDescription new];
    entityDescription.name = EPPZQueuedObjectEntityName;
    entityDescription.managedObjectClassName = NSStringFromClass(self);

    //Describe creationDate.
    NSAttributeDescription *creationDateDescription = [NSAttributeDescription new];
    creationDateDescription.name = @"creationDate";
    creationDateDescription.attributeType = NSDateAttributeType;
    creationDateDescription.attributeValueClassName = @"NSDate";
    creationDateDescription.defaultValue = nil;    

    //Describe archivedObject.    
    NSAttributeDescription *archivedObjectDescription = [NSAttributeDescription new];
    archivedObjectDescription.name = @"archivedObject";    
    archivedObjectDescription.attributeType = NSBinaryDataAttributeType;
    archivedObjectDescription.attributeValueClassName = @"NSData";
    archivedObjectDescription.defaultValue = nil;

    //Add attributes.
    entityDescription.properties = @[ creationDateDescription, archivedObjectDescription ];

    //Voila.
    return entityDescription;
}


@end

More details in the corresponding article: http://eppz.eu/blog/simple-core-data-sample/

I'm working on something similar and I'm thinking about creating a new core data class called "Properties", so I can set my core data objects to have a "relationship to many Properties". Each Property would have core data string-type attributes: "attribute", "type" and "value".

I think that should give enough flexibility to add properties to a core data object in the fly. If I happen to implement this, I will post it here

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top