为了找到一种方法,解决此处发布的问题: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,
答案 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;
我应该说我不需要“真实地”这样做,所以不能就完整的后果提出建议 - 例如,如果你需要推出一个噩梦,你可能会为自己做好准备新版本的模型。