NSManagedObject 中未保存的 NSSet 成员是不是会在保存时保留已删除的成员?

Posted

技术标签:

【中文标题】NSManagedObject 中未保存的 NSSet 成员是不是会在保存时保留已删除的成员?【英文标题】:Will unsaved NSSet members in an NSManagedObject persist the removed members on save?NSManagedObject 中未保存的 NSSet 成员是否会在保存时保留已删除的成员? 【发布时间】:2014-02-14 17:18:10 【问题描述】:

我今天遇到了一位同事提出的一个有趣的问题。起初答案似乎很简单,但后来我意识到我从未见过任何文档来支持我的假设。

给定一个NSManagedObject,比如Person,它与另一个对象,比如Friends,是一对多的关系,下面的代码——将friend1friend2持久化到数据存储?

NSManagedObjectContext *context = [a private context];
Person *aPerson = [NSEntityDescription insertNewObjectForEntityForName:@"Person"
                                                inManagedObjectContext:context];

NSMutableSet *friendsSet = [NSMutableSet new]; 
// Create some friends in the private context
Person *aFriend1 = [NSEntityDescription insertNewObjectForEntityForName:@"Friend"
                                                 inManagedObjectContext:context];
[friendsSet addObject:friend1];
Person *aFriend2 = [NSEntityDescription insertNewObjectForEntityForName:@"Friend"
                                                 inManagedObjectContext:context];
[friendsSet addObject:friend2];

// Add these friends to aPerson
[person addFriends:friendsSet];

// Alas! aPerson decides they want better friends.
NSMutableSet *betterFriendsSet = [NSMutableSet new]; 

Person *aFriend3 = [NSEntityDescription insertNewObjectForEntityForName:@"Friend"
                                                 inManagedObjectContext:context];
[betterFriendsSet addObject:friend3];
Person *aFriend4 = [NSEntityDescription insertNewObjectForEntityForName:@"Friend"
                                                 inManagedObjectContext:context];
[betterFriendsSet addObject:friend4];

// Dump those old friends
aPerson.friends = nil;
// Add the new friends
[person addFriends:betterFriendsSet];

// Save 
[context save:nil];

aPerson 在数据存储中是否有 2 个或 4 个朋友?我的假设是 2,因为不再有对朋友 1 和朋友 2 的任何强引用,它们应该被释放。然而,核心数据生成的访问器可能在幕后做更多的事情并持有对它们的强引用,在这种情况下,它们将被持久化到数据存储中。

【问题讨论】:

【参考方案1】:

你实际上是在问两个不同的事情:

friend1 和friend2 会被持久化到数据存储区吗?

是的。您将它们添加到托管对象上下文中,然后保存更改。它们是否被保存不受它们是否与aPerson 相关的影响。这与生成的访问器没有任何关系,只是您将它们添加到上下文中并且从未删除它们。如果您不想保留它们,则需要删除它们。

aPerson 在数据存储中是否有 2 个或 4 个朋友?

它有两个。由于您将friends 设置为nil,因此您删除了前两个朋友实例的关系。当上面的代码完成后,aPerson 有两个朋友。之前的朋友还在持久化存储中,但是已经和任何Person都没有关系了。

【讨论】:

【参考方案2】:

首先,为 Core Data 属性添加和删除集合成员的提供的 Core Data 方法是(示例属性是“Ratings”): 添加单个成员

- (void)addRatingsObject:(RatingsDB *)value;
- (void)removeRatingsObject:(RatingsDB *)value;

添加一组成员

- (void)addRatings:(NSSet *)value;
- (void)removeRatings:(NSSet *)value;

接下来,insertNewObjectForEntityForName 方法将为“Friend”创建 Core Data 对象,并且无论您对 NSSet 内容做什么,它们都会保存并保存。它们将与使用 nil 创建的“Person”实体解除链接。

按照描述完成后,您将拥有四个“朋友”记录。

【讨论】:

以上是关于NSManagedObject 中未保存的 NSSet 成员是不是会在保存时保留已删除的成员?的主要内容,如果未能解决你的问题,请参考以下文章

NSManagedObject 故障/无法获得由 NSManagedObject 处理的“原始”对象

具有未在模型中定义的附加属性的 NSManagedObject 子类

将方法添加到从 NSManagedObject 子类化的类

获取 NSManagedObject 未保存

插入的 NSManagedObject 无法保存时会发生啥情况?

NSManagedObject 保存或插入检查