NSCompoundPredicate 混合 AND 和 OR

Posted

技术标签:

【中文标题】NSCompoundPredicate 混合 AND 和 OR【英文标题】:NSCompoundPredicate Mixing AND and OR 【发布时间】:2014-03-02 23:57:38 【问题描述】:

我已经开始使用NSCompoundPredicate 来组合我的谓词,但是有一个问题。

这是一个谓词的示例:

Aircraft *obj = (Aircraft *)[self.managedObjectContext objectWithID:objID];
if ([predicateAircraft.predicateFormat isEqualToString:@""] || !predicateAircraft) 
    predicateAircraft = [NSPredicate predicateWithFormat:@"aircraft = %@", obj];
else

    NSPredicate *newPredicate = [NSPredicate predicateWithFormat:@"aircraft = %@", obj];
    NSPredicate *compoundPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:predicateAircraft, newPredicate, nil]];
    predicateAircraft = compoundPredicate;

AircraftNSManagedObject 的子类。这个谓词很好用,我只是循环了一些 Aircraft 对象,并将每个对象添加到谓词中,所以如果飞机 1 或飞机 2 或等...

我为几个属性执行此操作,代码与上面相同,但为不同的关系创建谓词等。基本上,用户可以过滤他们看到的数据,例如哪架飞机。

无论如何,一旦我为每一个都建立了一个谓词,我就会像这样组合它们:

NSPredicate *predicateFinal = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:predicateAircraft, predicateBatteries, predicatePilot, nil]];

这一次,使用AND 组合它们。但是,使用此谓词根本不会过滤我的数据。他们单独工作,但在最后一行中没有一次组合在一起。任何想法为什么?这就是我需要解决的问题。

我有一种预感,会不会是它在创造这个:aircraft1 OR aircraft2 OR ... AND ... pilot1 OR pilot2 OR...

通常您需要在每个位周围加上括号,例如在飞机和飞行员周围将它们分开,但复合材料不这样做?

实际上我得到的是:

aircraft = aircraftObj1 OR aircraft = aircraftObj2 AND pilot = pilotObj1 OR pilot = pilotObj2

我需要什么(我认为):

(aircraft = aircraftObj1 OR aircraft = aircraftObj2) AND (pilot = pilotObj1 OR pilot = pilotObj2)

无论如何,有什么想法吗?谢谢。

编辑:

predicateFinal 记录为:TRUEPREDICATE。不多,但显然是 TRUEPREDICATE:一个总是评估为 TRUE 的谓词,并且是一个谓词布尔值。天知道为什么要退回那个?!想必返回 true 就是为什么 fetch 结果没有视觉变化?当返回时没有变化,所有对象都被获取。

编辑 2:

现在真正的进步。我已经解决了 battery 对象是 NSSet 对多关系的一部分但执行 ANY battery 的任何问题。但它揭示了下一个问题(可能是一直以来的问题)。

【问题讨论】:

请发布NSLogpredicateFinal 输出。 注意:如果你已经有一个托管对象数组,你可以直接使用IN创建一个谓词:NSArray *uniqueAircraftIDs = [aircraftArray valueForKeypath:@"distinctUnionOfObjects.objectID]; NSPredicate *newPredicate = [NSPredicate predicateWithFormat:@"(objectID IN %@)", uniqueAircraftIDs]; 感谢您的提示(遗憾的是不是解决方案)。 predicateFinal 只输出TRUEPREDICATE 在创建最终谓词后放置一个断点并使用po predicateFinal 没错。 Apple 的文档说 TRUEPREDICATE 在没有子谓词时返回。您可以在合并之前对您的谓词Aircraft、Batteries 和 Pilot 进行 NSLog 记录吗? 【参考方案1】:

事实证明,NSCompoundPredicate 正在返回 TRUEPREDICATE,因为我的复合词中的第一个子谓词是 nil。 (简单啊?Doh!)因此,如果第一个子谓词是 nil,那么如果任何其他子谓词不是 nil 都没关系,它会停在那里并返回 TRUEPREDICATE 并且不过滤您的 fetch。

【讨论】:

我刚刚遇到了这个问题。谢谢!【参考方案2】:

可以在复合谓词中混合“AND”和“OR”我这样做了...

if ([searchCriteria isEqualToString:@"All"]) 
    [parr addObject:[NSPredicate predicateWithFormat:@"aID_Name     like[cd] %@",mySearchBar.text]];
    [parr addObject:[NSPredicate predicateWithFormat:@"aTrackingNum like[cd]         [parr addObject:[NSPredicate predicateWithFormat:@"aRegNum      like[cd] %@",mySearchBar.text]];
    predicate = [NSCompoundPredicate orPredicateWithSubpredicates:parr];
 

[parr removeAllObjects];
[parr addObject:predicate];
if (aGroups)
    [parr addObject:[NSPredicate predicateWithFormat:@"SUBQUERY(self.group, $x, $x.gID_Key IN %@).@count > 0",[aGroups valueForKey:@"gID_Key"]]];

predicate = [NSCompoundPredicate andPredicateWithSubpredicates:parr];
NSLog(@"%@",predicate);

【讨论】:

以上是关于NSCompoundPredicate 混合 AND 和 OR的主要内容,如果未能解决你的问题,请参考以下文章

NSCompoundPredicate 的 NSPredicate 数组

Xcode 6.1 中的 NSCompoundPredicate 错误

在 swift 3 中创建复杂的 NSCompoundPredicate

NSCompoundPredicate

NSCompoundPredicate 和 Cloudkit

NSCompoundPredicate 构造