我有一个核心数据应用,我试图将新对象添加到具有关系的实体。访问导致应用程序崩溃的关系实体出现问题保存
添加发生在工作表内。
保存操作:
-(IBAction)addNewRepair:(id)sender {
NSError *error = nil;
NSArray *fetchedObjects;
NSManagedObjectContext *context = [[NSApp delegate] managedObjectContext];
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Equipment" inManagedObjectContext:context];
[fetch setEntity:entityDescription];
[fetch setPredicate:[NSPredicate predicateWithFormat:@"(serial like %@)",[[serialPopUp selectedItem] title]]];
fetchedObjects = [context executeFetchRequest:fetch error:&error];
Equipment *equipmentObject = [fetchedObjects objectAtIndex:0];
Repairs *newRepair = (Repairs*)[NSEntityDescription
insertNewObjectForEntityForName:@"Repairs"
inManagedObjectContext:[[NSApp delegate] managedObjectContext]];
[newRepair setValue:invoiceNumberTextFeild.stringValue forKeyPath:@"invoiceNumber"];
[newRepair setValue:warrentyTextField.stringValue forKeyPath:@"warrantyDate"];
[newRepair setValue:repairReasonTextField.stringValue forKeyPath:@"repairDetails"];
[newRepair setValue:serviceProvidedTextField.stringValue forKeyPath:@"serviceSummary"];
[newRepair setValue:serviceDateTextField.stringValue forKeyPath:@"repairDate"];
[equipmentObject addRepairsObject:(Repairs *)newRepair];
if (![[[NSApp delegate] managedObjectContext] save:&error])
{
NSLog(@"couldn't save: %@", [error localizedDescription]);
}
NSLog((@"Repair Successfully added"));
[NSApp endSheet:self.sheet];
[self.sheet close];
}
获取方法:
-(void)fetchItems {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Equipment"];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Equipment" inManagedObjectContext:[[NSApp delegate] managedObjectContext]];
fetchRequest.propertiesToFetch = [NSArray arrayWithObject:[[entity propertiesByName] objectForKey:@"item"]];
fetchRequest.entity = entity;
fetchRequest.resultType = NSDictionaryResultType;
[fetchRequest setReturnsDistinctResults:YES];
itemDictionaries = [[[NSApp delegate] managedObjectContext] executeFetchRequest:fetchRequest error:nil];
NSLog(@"item: %@", itemDictionaries);
[nameController setContent:itemDictionaries];
self.itemSelection = [itemDictionaries firstObject];
self.predicate = [NSPredicate predicateWithFormat:@"item == %@", [[nameController selection] valueForKeyPath:@"item"]];
}
这种方法可能出现什么问题?
我的equipment.h文件实现了一个自定义访问器:
- (void)addRepairsObject:(Repairs *)value;
{
[self willChangeValueForKey:@"Repairs"];
[self setPrimitiveValue:value forKey: @"Repairs"];
[self didChangeValueForKey:@"Repairs"];
}
我得到的错误是:
2014-08-06 12:41:50.805 CNSplitView_Example [64803:4407] - [设备 copyWithZone:]:无法识别的选择器发送到实例0x6080002c0a10
即使equipment.h' lists
修复为
@property (nonatomic, retain) NSSet *repairs;
有人能指出我正确的方向吗?从我正在阅读的内容来看,这是一个常见问题(几乎总是在IOS上,而不是OS X应用程序),但没有广泛记录的解决方案。
我也试过这个:
NSMutableSet *newRepairObject = [NSMutableSet setWithObject:equipmentObject];
equipmentObject.repairs = newRepairObject;
同样的错误。
发现NSManagedObjects
不符合NSCopying
协议。 (那么为什么错误在该实体上产生copyWithZone?)
答案 0 :(得分:0)
问题在于addRepairsObject:方法。您正在使用属性访问器setPrimitiveValue:当您应该使用一对多关系访问器时。核心数据编程指南在Managed Object Accessor Methods
部分提供了一个示例@dynamic employees;
- (void)addEmployeesObject:(Employee *)value {
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"employees"
withSetMutation:NSKeyValueUnionSetMutation
usingObjects:changedObjects];
[[self primitiveEmployees] addObject:value];
[self didChangeValueForKey:@"employees"
withSetMutation:NSKeyValueUnionSetMutation
usingObjects:changedObjects];
}
替换“员工”的'维修',你应该没事。 NSCopying错误是红色鲱鱼:在核心数据中,相当多的东西发生在水下,一次崩溃可能会发送一些奇怪的碎片向上浮动,掩盖了真正的问题。