Hello all,
In page 40 of Marcus Zarra's Core Data book, he suggests that, since NSTreeController requires the same key for accessing all the objects in the hierarchy (for example, children) and that could imply less meaningful relationship names, you can write additional accessors for the desired relationships. I think that this is a great idea, but I am not sure of how to implement it.
Let me use Aperture’s data model as an example: You can have many libraries, each one of them can have many projects, and each of them can have many photos. So, if I name my Entities Library, Project, and Photo and their relationships projects, photos and nothing respectively, is the following a proper implementation for Library?
Library.h
@interface Library: NSManagedObject {
}
@property (nonatomic, retain) NSString *title;
@property (nonatomic, retain) NSSet *projects;
@property (nonatomic, retain) NSSet *children;
@property (nonatomic, retain) id parent;
@end
@interface Library (CoreDataGeneratedAccessors)
- (void)addProjectsObject:(Project *)value;
- (void)removeProjectsObject:(Project *)value;
- (void)addProjects:(NSSet *)value;
- (void)removeProjects:(NSSet *)value;
- (id)parent;
- (void)setParent;
@end
and Library.m
#include "Library.h"
@implementation Library
@dynamic title;
@dynamic projects;
- (NSSet*) children {
[self willAccessValueForKey:@"children"];
NSSet *set = [self valueForKey:@"projects"];
[self didAccessValueForKey:@"children"];
return set;
}
- (void) setChildren:(NSSet*)children {
[self willChangeValueForKey:@"children"];
[self setValue:children forKey:@"projects"];
[self didChangeValueForKey:@"children"];
}
- (id)parent {
[self willAccessValueForKey:@"parent"];
[self didAccessValueForKey:@"parent"];
return nil;
}
- (void)setParent:(id)parent {
// Proposed parent value is ignored. Libraries have no parent.
[self willChangeValueForKey:@"parent"];
[self didChangeValueForKey:@"parent"];
}
@end
Should children and parent be properties in the header file?
Is this the suggested implementation? Should I also include
addChildrenObject:
,removeChildrenObject:
,addChildren:
, andremoveChildren:
? And implement them? (Same goes for the parent methods.)I assume that children doesn’t appear at all in the Core Data model. Is that right? How are the reverse relationships inferred then?
Should I call [self willChangeValueForKey:@"children"] in setChildren: so children is KVO compliant? (Same for the other accessors.)
In page 41 M. Zarra recommends to implement NSOutlineDataSource instead of using NSTreeController due to “results [that] can be unexpected and unclear”. Does anyone know what are those limitations?
Finally, if I implement NSOutlineDataSource, would you recommend caching the fetch for the root objects? And if so, what is the proper way to maintain this cached array in sync with Core Data?
Thank you.
Best regards,
Jorge