如何以某种通用方式删除有序对多 CoreData 关系中的对象?
Posted
技术标签:
【中文标题】如何以某种通用方式删除有序对多 CoreData 关系中的对象?【英文标题】:How do I remove objects in an ordered to-many CoreData relationship in some generic way? 【发布时间】:2015-11-19 06:59:12 【问题描述】:我有一个联系人实体,它与另一个实体的电子邮件地址、电话有一对多的关系。
这种关系(自然称为“电子邮件,电话”)也是有序的,因此我可以在表格视图中显示联系人的电子邮件地址列表,并允许用户删除或修改每一个。据我所知,需要订购它们,以便我可以知道哪个被删除/修改:例如,如果用户点击第 1 行中的删除按钮,则应从关系中删除第二个电子邮件地址。没有被命令,我不知道该删除哪一个。
在生成 NSManagedObject 子类时,我在该类上获得了一个 NSOrderedSet 属性,CoreData 在 .h 文件中提供了一些访问器:
@interface Contact (CoreDataGeneratedAccessors)
- (void)insertObject:(PLEmail *)value inEmailsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromEmailsAtIndex:(NSUInteger)idx;
- (void)insertEmails:(NSArray<PLEmail *> *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeEmailsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInEmailsAtIndex:(NSUInteger)idx withObject:(PLEmail *)value;
- (void)replaceEmailsAtIndexes:(NSIndexSet *)indexes withEmails:(NSArray<PLEmail *> *)values;
- (void)addEmailsObject:(PLEmail *)value;
- (void)removeEmailsObject:(PLEmail *)value;
- (void)addEmails:(NSOrderedSet<PLEmail *> *)values;
- (void)removeEmails:(NSOrderedSet<PLEmail *> *)values;
- (void)insertObject:(PLTelephone *)value inTelephonesAtIndex:(NSUInteger)idx;
- (void)removeObjectFromTelephonesAtIndex:(NSUInteger)idx;
- (void)insertTelephones:(NSArray<PLTelephone *> *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeTelephonesAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInTelephonesAtIndex:(NSUInteger)idx withObject:(PLTelephone *)value;
- (void)replaceTelephonesAtIndexes:(NSIndexSet *)indexes withTelephones:(NSArray<PLTelephone *> *)values;
- (void)addTelephonesObject:(PLTelephone *)value;
- (void)removeTelephonesObject:(PLTelephone *)value;
- (void)addTelephones:(NSOrderedSet<PLTelephone *> *)values;
- (void)removeTelephones:(NSOrderedSet<PLTelephone *> *)values;
@end
我的问题是有什么办法可以使这段代码通用,所以应该删除isKindOfClass
检查:
NSArray *nestedArray = [orderedSet array];
id nestedObject = [nestedArray objectAtIndex:indexPath.row];
if ([nestedObject isKindOfClass:[PLEmail class]])
PLEmail *email = (PLEmail *)nestedObject;
[email MR_deleteEntity];
[self.contact removeEmailsObject:email];
else if ([nestedObject isKindOfClass:[PLTelephone class]])
PLTelephone *telePhone = (PLTelephone *)nestedObject;
[email MR_deleteEntity];
[self.contact removeTelephonesObject:telePhone];
【问题讨论】:
您不需要订购型号。相反,只需订购您的数据源。但那是另一回事了。 如果MR_deleteEntity删除了对象,删除规则为null,则该对象自动从联系人中删除。 删除规则无效,但它只是使对象为零,而不是删除.. 有序集中的对象可以为零吗? @Willeke 在有序集中没有对象不能为 nil。 【参考方案1】:如果您有互惠关系(如推荐的那样),您可以将电子邮件或电话实体上的联系关系设为 nil。这也会从联系人列表中删除该实体。
处理多重关系的示例代码
- (void)removeRelationship:(NSString *)relationshipKeyPath fromEntity:(NSManagedObject *)entity
[entity setValue:nil forKeyPath:relationshipKeyPath];
你会这样使用它:
[self removeRelationship:@"contact" fromEntity:unknownRelationshipForContact];
【讨论】:
“电子邮件或电话”实体与许多其他实体的互惠关系与“建筑物或财产等”实体一样。在那种情况下,我如何从联系人、建筑物、财产等的哪个实体中找到我必须使电子邮件为零? 我认为你根本无法在不了解任何上下文的情况下逃脱。你必须知道你在一方或另一方切断了哪种关系。最初的问题没有说明双方涉及多种关系。 但是,您可以有一个通用的removeContact:
方法,它不关心接收者是email
还是telephone
实体。然后对removeBuilding:
等做同样的事情。
还是一样,然后会检查建筑物或联系人,顺便说一句,它不是通用的..
实际上,您可以通过传入要切断的关系的 keyPath 使其更通用。然后您可以使用NSManagedObject
的原始方法来处理它。但是,这会导致代码脆弱,并且仍然需要在某处的 some 上下文。以上是关于如何以某种通用方式删除有序对多 CoreData 关系中的对象?的主要内容,如果未能解决你的问题,请参考以下文章
核心数据(添加唯一约束后):注释:修复丢失的删除传播以实现对多关系