开发者

NSTreeController fetch predicate based on transient isRoot exceptions

开发者 https://www.devze.com 2023-01-14 08:37 出处:网络
My document-based Cocoa application uses a NSOutlineView/NSTreeController combo, bound to the document\'s Core Data store.My NSTreeController has the fetch predicate isRoot == YES.isRoot is a transien

My document-based Cocoa application uses a NSOutlineView/NSTreeController combo, bound to the document's Core Data store. My NSTreeController has the fetch predicate isRoot == YES. isRoot is a transient boolean attribute with a default value of NO. My root model's awakeFromInsert calls:

[self setIsRoot:[NSNumber numberWithBool:YES]];

I'm able to add objects to the hierarchy just fine, but when I try to load a document I just saved, I get an exception:

[<NSDictionaryMapNode 0x1001a8190> valueForUndefinedKey:]: this class is not key value coding-compliant for the key isRoot.

I can work around this exception and successfully load a newly-saved document if I change the isRoot attribute to non-transient in the xcdatamodel, but based on my understanding of the transient flag it should not cause a problem, and this really isn't the kind of data that should be persisted.

I have also tried implementing -isRoot in the NSManagedObject su开发者_StackOverflowbclasses to return the appropriate fixed value, as well as making the same setIsRoot: call within awakeFromFetch, both to no avail.

Is there some other subtlety I'm missing? I can't imagine that fetch predicates don't support transient attributes. I don't know much about the inner workings of Core Data but it seems interesting that it's trying to look up isRoot on the store-specific class and not my NSManagedObject subclass.


I can't imagine that fetch predicates don't support transient attributes.

After a bit of research, I can tell you that they don't. See this document. Quote:

You cannot fetch using a predicate based on transient properties (although you can use transient properties to filter in memory yourself).

I've put together a test project and can verify I get exactly the same error as you do.

When I need to filter out the root nodes in a tree, I use a fetch predicate of parent == nil instead of a transient attribute.

I understand your reaction - I too wanted way of having an attribute specifically called isRoot too. My guess is it's possible, but it'd take so much code it's just not worth the hassle.

Oh, and if you're dealing with core data any more than a little, mogenerator will make your life much easier.


Another option is to have a separate class for the top-level nodes, use that class name as "Entity Name" and leave "Fetch Predicate" blank. As long as the child nodes have the same values as the top-level node (I use a common superclass/entity inheritance), everything still works.


Have you made sure that the NSTreeController is set to control an entity rather than a class?

From your error, it looks like it might be set to a class with the default - NSMutableDictionary.

NSTreeController fetch predicate based on transient isRoot exceptions

I'd also argue that maybe isRoot could be persisted. It depends on what you're trying to do with your app, of course, but if it's a tree view that gets loaded on app run I'd either make isRoot persist.

0

精彩评论

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