How to add attributes to an existing Core Data ent

2019-07-22 08:01发布

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.

5条回答
三岁会撩人
2楼-- · 2019-07-22 08:40

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/

查看更多
乱世女痞
3楼-- · 2019-07-22 08:42

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.

查看更多
叼着烟拽天下
4楼-- · 2019-07-22 08:44

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

查看更多
forever°为你锁心
5楼-- · 2019-07-22 08:56

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

查看更多
SAY GOODBYE
6楼-- · 2019-07-22 09:05

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.

查看更多
登录 后发表回答