views:

37

answers:

1

I have a 1-to-many relationship in a Core Data graph, and I'm trying to understand the difference between using a CoreDataGeneratedAccessors method and a simple assignment to alter a relationship. For example, the Core Data Programming Guide has a department and employee example. In that example they use the CoreDataGeneratedAccessors to hire and fire employees:

[aDepartment addEmployeesObject:newEmployee];
[aDepartment removeEmployeesObject:firedEmployee];

They don't define an inverse relationship, but say "department" is the inverse relationship to "employees". Should the following then accomplish the same thing?

newEmployee.department = aDepartment
firedEmployee.department = nil;

According to the Manipulating Relationships and Object Graph Integrity section of the Core Data Programming Guide, the later examples should automatically fix all relationships to maintain graph consistency. If that's the case, is there any reason to use the CoreDataGeneratedAccessors when an inverse relationship exists? Does using the CoreDataGeneratedAccessors maintain graph consistency on inverse relationships?

+1  A: 

They don't define an inverse relationship, but say "department" is the inverse relationship to "employees". Should the following then accomplish the same thing?

Both operations have the same result no matter which end of the relationship (with inverse) you modify.

If that's the case, is there any reason to use the CoreDataGeneratedAccessors when an inverse relationship exists? Does using the CoreDataGeneratedAccessors maintain graph consistency on inverse relationships?

Consistency is not an issue with both methods. For performance reasons it is very important to modify large relationships with apropriate methods.

Solution 1 (firing all employees of a department)

for (Employee* employee in aDepartment.employees)
{
  employee.department = nil
}

Solution 2

aDepartment.employees = nil;

The first solution would trigger an update of a (table-)view after each operation while the second would result in exactly one update of all views. This can be a big difference if you handle a a large amount of objects.

If you need more in depth information, I think similar topics have already been discussed on SO.

Martin Brugger
Martin- thanks for the reply. I have situation where I can use [aDepartment addEmployeesObject:newEmployee] once, but subsequent calls within the app (regardless if it's on another newEmployee) doesn't update. However, replacing this with newEmployee.department=aDepartment always works. The behaviours of the two calls seem inconsistent, so I'm puzzled they are supposed to do the same thing. Ideas?
chris
@chris -- it sounds like you don't have a inverse relationship between the Department entity and the Employee entity.
TechZen
I only experienced such behavior in certain special situations when observings being triggered in certain core data change processing and observer code modifying relations. (this was a bug of my code)
Martin Brugger
@TechZen: I'm quite certain the inverse relationships are correct since I can access the entities in both directions; in one direction the department and in the other the employees NSSet. Oddly, the [aDepartment addEmployeesObject:newEmployee] call works once per launch of the app, but fails on subsequent calls.
chris
@chris -- no idea what would cause it then. Do you have a custom accessor for Employees? If you use primitive accessors anywhere they do not trigger KVO. You have to call those yourself.
TechZen