如何使用 "empty" 谓词创建 NSCompoundPredicate

How to create NSCompoundPredicate with "empty" predicate

我尝试通过 NSCompoundPredicate 将多个单独的谓词组合成一个,但可能会发生一个或多个谓词未构造的情况,因为所有对象都应从 CoreData 实体中检索(因此实际上不需要谓词)。

if isGenreFilterOn {
    genrePredicate = NSPredicate(format: "genID == \(genreID)")
}
if searchFor != "" {    
    bookPredicate = NSPredicate(format: "bokName CONTAINS[cd] %@", searchFor)
}
let predicate = NSCompoundPredicate(type: .and, subpredicates: [genrePredicate, bookPredicate])

如果未构造任何谓词,应用程序将失败。避免许多 if 子句的最佳方法是什么,我应该构建从实体中检索所有对象的谓词还是有什么聪明的方法?谢谢

你所说的空谓词是指始终计算为“真”的谓词。你可以这样做——当你不需要它们时,使用 NSPredicate(value: true) 代替你的任何一个谓词。使用一个始终为真的谓词,您的化合物会评估另一个谓词。如果两者都为真,复合词也为真,就等于没有谓词。

您可以动态构建一个仅包含所需谓词的数组,而不是创建“空”谓词:

var predicates = [NSPredicate]() // Start with empty list.
if isGenreFilterOn {
    // Add genre predicate:
    predicates.append(NSPredicate(format: "genID == \(genreID)"))
}
if !searchFor.isEmpty {
    // Add book predicate:
    predicates.append(NSPredicate(format: "bokName CONTAINS[cd] %@", searchFor))
}
// ... more criteria ...

// Combine all predicates:
let predicate = NSCompoundPredicate(type: .and, subpredicates: predicates)

可以轻松添加更多可选(或非可选)标准。即使谓词数组为空,这也能正常工作。


备注:注意谓词格式字符串中的字符串插值。

NSPredicate(format: "genID == \(genreID)")
如果 genreID 是一个数字,

没问题,但如果它是一个字符串并且包含任何特殊字符或谓词的保留关键字,则可能会在运行时崩溃。