如何设置从一个对象到另一个对象的引用?

时间:2010-04-07 07:13:41

标签: iphone core-data

解决

我拼错了物业部门 - >部门。 感谢您的答案和一个很大的 SORRY

您好,

想象一下员工和部门的明显模式,每个员工必须参考一个部门,每个部门可能没有多少员工。

对于员工我有一个指向Department的指针,我将其值设置为相关部门对象的地址。

对于部门我有一个NSSet,我可以添加员工。

问题在于,当我创建新员工和新部门时,对象存在于某个地方的内存中。从Employee到Department的引用,反之亦然,包含这些地址。当我获取数据时,它将位于不同的位置。所以不清楚这些对象之间的连接是如何完成的。

以下是我应该理解的代码:

    // Fetch Plist object
    NSDictionary *plistDictionary = [[NSDictionary alloc] initWithDictionary:plistData];

    // Create Department Entity
    Department *department = (Department *)[NSEntityDescription 
                                insertNewObjectForEntityForName:@"Department" 
                                inManagedObjectContext:managedObjectContext];
    // Set properties
    [department setName:[plistDictionary valueForKey:@"department"]];

    // Create Employee entity
    Employee *employee = (Employee *)[NSEntityDescription 
                             insertNewObjectForEntityForName:@"Employee" 
                             inManagedObjectContext:managedObjectContext];

    // Set properties
    [employee setFileName:[plistDictionary valueForKey:@"picture"]];
    [employee setName:[plistDictionary valueForKey:@"name"]];

    // Set relationship
    [employee setDepartment:department];
    [department addEmployee:employee];

    // Save data to core data
    [self saveAction];

这是我得到的错误:

      2010-04-08 16:06:11.295 Paparazzi2[2656:207] ERROR:saveAction. Unresolved Core Data Save error Error Domain=NSCocoaErrorDomain Code=1570 UserInfo=0x3d1c6f0 "Operation could not be completed. (Cocoa error 1570.)", {
NSLocalizedDescription = "Operation could not be completed. (Cocoa error 1570.)";
NSValidationErrorKey = department;
NSValidationErrorObject = <Employee: 0x3d13a30> (entity: Employee; id: 0x3d16670 <x-coredata:///Employee/t8C950118-C388-4020-8CD9-1F49138A94193> ; data: {
picture = "mike.jpg";
name = "Mike Smith";
department = nil;

}); }

谢谢, Tzur。

2 个答案:

答案 0 :(得分:2)

Hey Tzur,您提供的代码的一个问题是,您尝试为部门关系分配一个非托管对象的值。

如果Department对象尚不存在,则应首先创建该对象,并将该对象用作部门关系的值。

我会替换这一行:

[employee setDepartment:[object valueForKey:@"department"]];

有了这个:

Department *myDepartment = [self fetchDepartmentNamed:[object objectForKey:@"department"]
                               inManagedObjectContext:[self managedObjectContext]];
if (!myDepartment) {
  /* no existing department with that name.. create one */
  myDepartment = (Department *)[NSEntityDescription insertNewObjectForEntityForName:@"Department" inManagedObjectContext:[self managedObjectContext]];
  [myDepartment setName:[object objectForKey:@"department"]];
}
/* assign the relationship to the department managed object */
[employee setDepartment:myDepartment];

这假设您已经定义了一个方法-(Department *)fetchDepartmentNamed:inManagedObjectContext:],该方法将构建一个获取请求并获得一个具有您提供的名称的部门(也假设您的部门名称是唯一的)

或者,您可以将员工添加到myDepartment的“员工”关系中,这样可以获得相同的结果。


好的,所以你已经更新了你的代码,现在你有了这个:

// Set relationship
[employee setDepartment:department];
[department addEmployee:employee];

你应该做的,一个或另一个......不是两者兼而有之。检入您选择了两个实体的关系的“反向:”的托管对象模型。如果您设置其中一个关系,Core Data将管理关系的反向(反向)。

答案 1 :(得分:0)

您不能在NSDictionary中使用nil。如果您没有合成类来表示托管对象,则必须使用NSNull类。因此,假设employeeNSManagedObject的实例并代表您的Employee实体:

[employee setValue:[NSNull null] forKey:@"department"];

这用于切断此Employee实例与其之前部门之间的任何关系。但是,如果执行将此设置为nil,则department属性必须是可选的,否则当您尝试保存对象图(上下文)时,您将遇到验证错误。