Help with CoreData making a NSPredicate - Recursive Searching

淺唱寂寞╮ 提交于 2019-11-29 16:19:18
TechZen

The problem is that this only goes up one level. So if I have folder1 -> folder2 -> folder3 -> folder4, and folder1 is secure. Then folder2 is not show but folder3 and folder4 are.

You can't recursively walk relationships in predicates because keypaths only describe the relationship between the abstract entities and not the concrete, living managed objects that actually contain the data. An entity graph can be very simple yet generate a vastly complex graph of live objects when populated at runtime. You can't logically capture the complexity of that live graph with a simple keypath.

In this case, you have a Folder entity which has a relationship to itself called parent and an attribute of secure. Therefore, a keypath can only describe at most those two properties with path parent.secure. You can't create a keypath of parent.parent.secure because no such relationship actually exists in the entity graph. Such a path only exist sometimes in the live object graph. It would be logically impossible to hard code a path that might or might not exist depending on the particulars of the data at any given time.

This type of situation is where the ability to create customized NSManagedObject subclasses really comes in handy. Your Folder entites don't have to be just dumb data, you can add behaviors to them so that each object can access its own state and return different data as needed.

In this case, I would recommend adding a transient boolean property named something like hasSecureAncestor. Then create a custom getter method like:

- (BOOL) hasSecureAncestor{
    BOOL hasSecureAncestor=NO;
    if (self.parent.secure==kNoSecurity) {
        hasSecureAncestor=YES;
    }else {
        if (self.parent.parent!=nil) {
            hasSecureAncestor=self.parent.hasSecureAncestor;
        }else {
            hasSecureAncestor=NO;
        }
    }
    return hasSecureAncestor;
}

Then just create a predicate to test for "hasSecureAncestor==YES". The custom accessor will walk an arbitrarily deep recursive relationship looking for a secure ancestor.

Why not just grab all Folder entities with kNoSecurity?

NSPredicate *pred = [NSPredicate predicateWithFormat:@"secure = %@ ", [NSNumber numberWithInteger:kNoSecurity]];

How about going back up through the relationship:

NSPredicate *pred = [NSPredicate predicateWithFormat:"parent.secure = %@", [NSNumber numberWithInteger:kNoSecurity]];
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!