我有一个 Contact 实体,它与另一个存储有关电子邮件地址的信息的实体具有一对多的关系(它被称为 TypedValue,因为它还包括电子邮件类型,如个人、工作等)。
这种关系(自然称为“电子邮件”)也是有序的,因此我可以在表格视图中显示联系人的电子邮件地址列表,并允许用户删除或修改每一个。据我所知,需要订购它们,以便我可以知道哪个被删除/修改:例如,如果用户点击第 1 行中的删除按钮,则应从关系中删除第二个电子邮件地址。没有被订购,我不知道要删除哪一个。
在生成 NSManagedObject 子类时,我在该类上获得了 NSOrderedSet 属性,CoreData 在 .h 文件中提供了一些访问器:
@interface Contact (CoreDataGeneratedAccessors)
- (void)insertObject:(TypedValue *)value inEmailsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromEmailsAtIndex:(NSUInteger)idx;
- (void)insertEmails:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeEmailsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInEmailsAtIndex:(NSUInteger)idx withObject:(TypedValue *)value;
- (void)replaceEmailsAtIndexes:(NSIndexSet *)indexes withEmails:(NSArray *)values;
- (void)addEmailsObject:(TypedValue *)value;
- (void)removeEmailsObject:(TypedValue *)value;
- (void)addEmails:(NSOrderedSet *)values;
- (void)removeEmails:(NSOrderedSet *)values;
@end
我的问题是只有其中一些工作。addEmailsObject:
工作得很好,但删除或替换方法不行。如果我尝试用这个调用替换集合中的一个对象:
// newVal is a properly-built object requested from the managed object context
[self replaceObjectInEmailsAtIndex:index withObject:newVal];
我得到一个讨厌的错误:
2013-08-16 16:51:19.687 AppName[43837:c07] -[Contact replaceObjectInEmailsAtIndex:withObject:]:无法识别的选择器发送到实例 0xa56a800 2013-08-16 16:51:19.694 AppName[43837:c07] *终止应用程序由于未捕获的异常 'NSInvalidArgumentException',原因:'-[Contact replaceObjectInEmailsAtIndex:withObject:]:无法识别的选择器发送到实例 0xa56a800'
根据我的阅读,如果进行调用的对象(在本例中为 Contact 对象)是使用常规 alloc/init 创建的,而不是从托管对象上下文中请求的,则可能会发生这种情况,但我正在正确地执行该部分.
我还尝试获取 NSOrderedSet 对象的可变副本,以进行更新然后替换集合:
NSMutableOrderedSet *newSet = [self.emails mutableCopy];
[newSet replaceObjectAtIndex:index withObject:newVal];
[self setEmails:newSet];
这没有引发任何错误,但做了一些奇怪的事情:我的界面开始显示不正确的值,我不确定发生了什么。
那么:如果不使用 CoreData 声称提供的 mutators,那么替换和删除对象的正确方法是什么?