如何以编程方式添加Fetched属性(到DataModel)?

时间:2016-02-01 04:36:32

标签: ios core-data

为了找到一种方法,解决此处发布的问题:Core Data Lightweight Migration not working when a Fetched Property is present

我正在尝试在对实体执行任何其他操作之前,以编程方式(在DataModel上)向实体添加Fetched Property

但是我在这一点上所尝试的却失败了。这是我使用的代码:

    NSEntityDescription *myEntity = [NSEntityDescription entityForName:@"EntityName"
                                                inManagedObjectContext:context];
    NSFetchedPropertyDescription *myFetchProp = [[NSFetchedPropertyDescription alloc] init];
    [myFetchProp setName:@"myFetchPropName"];
    [myEntity setProperties:[[myEntity properties] arrayByAddingObject:myFetchProp]];

最后一行发生了崩溃,这是我在调试器中可以看到的:

(lldb) bt
* thread #1: tid = 0xc2b17, 0x0000000180c3bf48 libobjc.A.dylib`objc_exception_throw, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
    frame #0: 0x0000000180c3bf48 libobjc.A.dylib`objc_exception_throw
    frame #1: 0x00000001830e0b70 CoreData`-[NSManagedObjectModel(_NSInternalMethods) _throwIfNotEditable] + 80
    frame #2: 0x00000001830aa0f8 CoreData`-[NSEntityDescription setProperties:] + 52
  * frame #3: 0x000000010007b2b4 parl100`-[XYZLib transferDataFromDefaultStoreToUserStore](self=0x000000015654dba0, 

2 个答案:

答案 0 :(得分:1)

创建字段

+(NSEntityDescription*)entityDescription
{
NSEntityDescription *entityDescription = [NSEntityDescription new];
entityDescription.name = @"EntityName";

entityDescription.managedObjectClassName = NSStringFromClass(self);

//Describe date attribute creation.
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;
}

获取

NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"EntityName"];

NSError *error;
id results = [appdel.managedObjectContext executeFetchRequest:request error:&error];
int i=100;
if ([results count])
{
    for (NSManagedObject *object1 in results)
    {
        NSManagedObjectClass  *object = (NSManagedObjectClass *)object1;
    }
}

保存

        NSManagedObject   *object = [NSEntityDescription insertNewObjectForEntityForName:@"EntityName" inManagedObjectContext:self.managedObjectContext];
        NSManagedObjectClass  *polyline = (NSManagedObjectClass *)object;
        polyline.json_string=request.responseString;
       if (![self.managedObjectContext save:&error1]) {
            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
        }

答案 1 :(得分:0)

来自NSManagedObjectModel class reference

  

托管对象模型是可编辑的,直到它们被对象图管理器(托管对象上下文或持久性存储协调器)使用。

因此,您需要在构建CoreData堆栈时修改模型,而不是在使用上下文时。因此,如果您从捆绑包中获得基本模型,则可以使用以下内容:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"YourApp" withExtension:@"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSManagedObjectModel *newMOM = [mom copy];
NSEntityDescription *myEntity = [[newMOM entitiesByName] objectForKey:@"EntityName"];
NSFetchedPropertyDescription *fp = [[NSFetchedPropertyDescription alloc] init];
fp.name = @"myFetchedPropertyName";
NSFetchRequest *fpFetch = [[NSFetchRequest alloc] init];
// configure fetched property fetch request
fp.fetchRequest.entity = myOtherEntity;
fp.fetchRequest.predicate = myFPPredicate;
// Add the fetched property to the entity's properties:
NSMutableArray *currentProperties = [NSMutableArray
                                     arrayWithArray:[myEntity properties]];
[currentProperties addObject:fp];
myEntity.properties = currentProperties;
return newMOM;

我应该说我不需要“真实地”这样做,所以不能就完整的后果提出建议 - 例如,如果你需要推出一个噩梦,你可能会为自己做好准备新版本的模型。