2014-02-07 98 views
0

我有一个核心数据问题。我有一个名为“Group”的实体,以及其他名为“Contact”的实体。这些实体之间存在“多对多”的关系,因为一个组可能有许多联系人(该组的成员),并且联系人可能有许多组(成为多个组的成员)。核心数据不会覆盖对象

所以,这是关系:

集团< < ----- >>联系

我需要的是插塞触头(新的或现有的)作为现有组的成员。 我的问题是什么?那么......如果我创建了一个新的联系人,我可以插入它们,但如果联系人已经存在,Core Data不会覆盖并保存它。

这里是我的代码:

- (void)saveMemberInGroup:(Message *)message 
{ 
    GroupInfo *groupInfo = message.group; 
    UserInfo *member = message.user; 

    AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate; 
    NSManagedObjectContext *context = [app managedObjectContext]; 
    NSError *error; 

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:CONTACT_ENTITY 
               inManagedObjectContext:context]; 
    [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"ident == %@", [member ident]]]; 
    [fetchRequest setEntity:entity]; 
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error]; 

    //Here I check if the contact exists. 
    Contact *contact; 
    if ([fetchedObjects count] == 0) { 
     contact = [NSEntityDescription insertNewObjectForEntityForName:CONTACT_ENTITY 
               inManagedObjectContext:context]; 
     [contact setIdent:[NSString stringWithFormat:@"%@", [member ident]]]; 
    } else { 
     contact = [fetchedObjects objectAtIndex:0]; 
    } 

    //Now I make a new request for the group. 
    fetchRequest = [[NSFetchRequest alloc] init]; 
    entity = [NSEntityDescription entityForName:GROUP_ENTITY 
         inManagedObjectContext:context]; 
    [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"ident == %@", [groupInfo ident]]]; 
    [fetchRequest setEntity:entity]; 
    fetchedObjects = [context executeFetchRequest:fetchRequest error:&error]; 

    Group *group = [fetchedObjects objectAtIndex:0]; 

    //Now, I overwrite the group and the contact. 
    [[group members]addObject:contact]; 
    [[contact memberGroups]addObject:group]; 

    [context save:&error]; 
} 

这里是我的集团法人:

@interface Group : NSManagedObject 

@property (nonatomic, retain) NSString *ident; 
@property (nonatomic, retain) NSString *name; 
@property (nonatomic, retain) NSMutableSet *members; 

@end 

和我联系实体:

@interface Contact : NSManagedObject 

@property (nonatomic, retain) NSString *ident; 
@property (nonatomic, retain) NSString *name; 
@property (nonatomic, retain) NSMutableSet *memberGroups; 

@end 

注:

这真的很奇怪......当我检查是否已成功更新对象时,一切似乎都没有问题,组和联系人都正确更新了NSSet,但是当我重新启动应用程序时(我的意思是,最终确定并重新启动它,或者按XCode中的“play”),Core Data只保存了与创建的新联系人的关系!!

实施例:

  1. 创建Contact1并保存在组1。
  2. 创建联系人2并保存到组1中。
  3. 现有联系人1并保存在组2中。
  4. 创建联系人3并保存到组2中。

如果我检查核心数据时,我的应用程序正在运行,我将在组1(联系人1,联系人2),并在组2(联系人1,联系人3)。

然后我重新启动应用程序并再次检查核心数据,现在我已经在Group1(Contact1,Contact2)和Group2(Contact3) !!核心数据已经失去了联系人1和联系人2之间的关系,并且每次我在组和现有联系人之间建立关系时都会发生这种情况。

我在做什么错?

非常感谢!

回答

4

您应该使用Xcode菜单中的“Editor - > Create NSManagedObject Subclasses ...”为您的实体创建类文件。一对多关系由NSSet, 而非NSMutableSet表示,因此您无法通过添加对象直接对其进行修改。

一旦你这样做,你可以用

[group addMembersObject:contact]; 

或可替代

[contact addMemberGroupsObject:group]; 

核心数据自动更新反向关系,所以也无所谓 其中一个增加一个额外的对象group.members你选。

+0

我会推荐mogenerator工具来创建你的类而不是Xcode。 http://rentzsch.github.io/mogenerator/ –

+0

请注意这种自动生成的方法,如'[group addMembersObject:contact];'。在以前的版本中,它们必须被重写。 – Foriger

+0

@MikePollard:这可能是使用Xcode或mogenerator(我仍然使用Xcode)的口味问题,但您可以将其作为替代方案提及它是很好的。 –