views:

33

answers:

2

I have app that stores tree structure in CoreData. There is an ManagedObject, "Item", and it has attributes:

  • itemId (string)
  • List item
  • title (string)
  • parentId (string)
  • parent (relationship to Item)
  • parentTitle (string)

parentId points to another Item object.

How do I make property parentTitle to be filled automatically with title of parent Item ?

A: 

This is a possibility to achieve the desired functionality:

// implement in Item.m
// manages KVO notifications
+ (NSSet *)keyPathsForValuesAffectingParentTitle
{
    return [NSSet setWithObjects:@"parent.title", nil];
}

// getter for parentTitle
- (NSString*) parentTitle
{
    return [self valueForKeyPath:@"parent.title"];
}

additionally declare the property for parentTitle as readonly in Item.h There is no need to declare a Core Data attribute "parentTitle".

The only problem I see with this solution is the following:

  • Item A is parent of item B
  • A gets turned into fault
  • B is still active and some View is bound to B.parentTitle

The view gets a notification because of the dependency declared with keyPathsForValuesAffecting, still object A is already faulted (and on shutdown unable to be unfaulted again) does Core Data manage such faulting&observation problems automatically?

Martin Brugger
Thanks for the solution!Is it a bad practice to have such parentTitle property? Shouldn't it be encouraged to always access the value through parent.title?
Rod
I think Marcus gave a great explanation when to use which solution.
Martin Brugger
+1  A: 

While Martin's suggestion is a good solution for derived values, my question on yours is, why would you want this? You are not manipulating the value from the parent at all, ever. Since you are just accessing it, access the parent directly via KVC such as:

Item *item = ...;
NSString *title = [item valueForKeyPath:@"parent.title"];
//Do something with title

The only time you would want to use the keyPathsForValues... functionality is if you are changing something based on that value. If you are just accessing it, use KVC directly.

Marcus S. Zarra