如何为可以返回 nil 的 NSPredicate 创建惰性 var
Posted
技术标签:
【中文标题】如何为可以返回 nil 的 NSPredicate 创建惰性 var【英文标题】:How do I create a lazy var for an NSPredicate that can return nil 【发布时间】:2017-06-22 17:50:03 【问题描述】:我有一个可以过滤和排序的UITableView
。当用户选择过滤器选项时,我尝试使用名为 liftUuidPredicate
的 lazy var
来构造谓词。用户的选择存储在UserDefaults
中,但如果没有选择过滤器,UserDefaults.logFilterLiftUuid()
中将没有任何值,这导致我的应用程序崩溃并出现错误:
NSInvalidArgumentException',原因:'*** -copyWithZone:不能 发送到 NSPredicate 类的抽象对象:创建一个具体的 实例!
显然我需要创建一个 NSPredicate 的具体实例,但是在没有谓词的情况下我不知道该怎么做。
// throws the 'Create a concrete instance' error
lazy var liftUuidPredicate: NSPredicate =
guard let liftUuid = UserDefaults.logFilterLiftUuid() else return NSPredicate()
return NSPredicate(format: "uuid = %@", liftUuid)
()
// fetchedResultsController
func fetchLiftEvents() -> NSFetchedResultsController<NSFetchRequestResult>
let moc = stack.managedObjectContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "LiftEvent")
fetchRequest.predicate = liftUuidPredicate
if let sortBy = UserDefaults.logSortSelection() fetchRequest.sortDescriptors = [NSSortDescriptor(key: sortBy, ascending: false)]
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
do
try fetchedResultsController!.performFetch()
catch
fatalError("Unable to fetch Lift Events: \(error)")
return fetchedResultsController!
NSPredicate()
的可用方法需要一种格式和某种形式的参数,当我希望没有谓词时,它们将不起作用。在guard let
语句中,我也尝试了return NSPredicate(value: false)
,但正如我所料,fetchRequest 然后没有返回任何记录。
我怎样才能做到这一点?
【问题讨论】:
【参考方案1】:NSPredicate
是一个抽象类。您不能拥有NSPredicate()
,您必须使用所需的信息对其进行实例化以获取具体实例。
关键是将liftUuidPredicate
的类型从NSPredicate
更改为NSPredicate?
,如果guard
失败,则不要返回NSPredicate()
,而是返回nil
。
我添加了一些样板代码来使我的 sn-p 编译,因此您可以根据需要进行更改。
`extension UserDefaults
class func logFilterLiftUuid() -> String?
return "bar"
class func logSortSelection() -> String?
return "bar"
class Foo
let stack = NSFetchedResultsController<NSManagedObject>()
var fetchedResultsController = NSFetchedResultsController<NSFetchRequestResult>()
// throws the 'Create a concrete instance' error
lazy var liftUuidPredicate: NSPredicate? =
guard let liftUuid = UserDefaults.logFilterLiftUuid() else return nil
return NSPredicate(format: "uuid = %@", liftUuid)
()
// fetchedResultsController
func fetchLiftEvents() -> NSFetchedResultsController<NSFetchRequestResult>
let moc = stack.managedObjectContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "LiftEvent")
fetchRequest.predicate = liftUuidPredicate
if let sortBy = UserDefaults.logSortSelection() fetchRequest.sortDescriptors = [NSSortDescriptor(key: sortBy, ascending: false)]
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
do
try fetchedResultsController.performFetch()
catch
fatalError("Unable to fetch Lift Events: \(error)")
return fetchedResultsController
【讨论】:
以上是关于如何为可以返回 nil 的 NSPredicate 创建惰性 var的主要内容,如果未能解决你的问题,请参考以下文章
如何为 CoreData 多对多关系编写 NSPredicate
如何为 CoreData 中包含 NSArray 的二进制数据创建 NSPredicate?