开发者

How to set a reference from one object to another?

开发者 https://www.devze.com 2022-12-26 13:19 出处:网络
开发者_如何学PythonSOLVED I misspelled the property department -> Department. Thanks for the answers anda big SORRY
开发者_如何学Python

SOLVED

I misspelled the property department -> Department. Thanks for the answers and a big SORRY

Hi,

Imagine the obvious model of employees and departments, where each employee must refer to a single department, and each department may have none to many employees.

For Employee I have a pointer to Department, and I set its value to the address of the object of the relevant Department.

For Department I have a NSSet, to which I can add employees.

The problem is that when I create a new employee and a new department, the objects exist in the memory at some place. The reference from Employee to Department, and vice versa, contains these addresses. When I'll fetch the data it will be located at a different location. So it is not clear how the connection between these objects is done.

Here is the code as I understand it should be:

    // 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];

And here is the Error I get:

      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;

}); }

Thanks, Tzur.


Hey Tzur, one problem with the code you provide is that you're trying to assign the department relationship a value that is not a managed object.

You should first create the Department object if it doesn't already exist, and use that object as the value of the department relationship.

I would replace this line:

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

With this:

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];

This assumes you have defined a method -(Department *)fetchDepartmentNamed:inManagedObjectContext:] that will build a fetch request and get a Department with the name you provide (also assumes your department names are unique)

Alternatively, you could just add the employee to myDepartment's "employees" relationship, and it would achieve the same result.


Ok, so you have updated your code, and now you have this:

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

You should have done, one or the other... not both. Check in the managed object model that you have selected the "Inverse:" of the relationship for both entities. If you set one of the relationships, Core Data will manage the reverse (inverse) of the relationship.


You can't use nil in an NSDictionary. If you haven't synthesized classes to represent your managed objects, you have to use the NSNull class. So, assuming employee is an instance of NSManagedObject and represents your Employee entity:

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

This is used to sever whatever relationship this instance of Employee had with its previous department. If you do set this to nil, however, the department attribute must be optional or you will have a validation error when you try to save your object graph (context).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号