我有UITableView
可以过滤和排序。当用户选择过滤器选项时,我正在尝试使用名为lazy var
的{{1}}来构造谓词。用户的选择存储在liftUuidPredicate
中,但如果没有选择过滤器,则UserDefaults
中没有任何值,这会导致我的应用崩溃并显示错误:
NSInvalidArgumentException',原因:'*** -copyWithZone:不能 发送到NSPredicate类的抽象对象:创建一个具体的 实例!
显然我需要创建一个NSPredicate的具体实例,但是当没有谓词时我不知道该怎么做。
UserDefaults.logFilterLiftUuid()
// 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
但是,正如我所料,fetchRequest然后没有返回任何记录。
我该如何做到这一点?
答案 0 :(得分:0)
NSPredicate
是一个抽象类。您不能拥有NSPredicate()
,必须使用所需信息对其进行实例化以获取具体实例。
关键是将liftUuidPredicate
的类型从NSPredicate
更改为NSPredicate?
,如果NSPredicate()
,则不会返回nil
返回guard
失败。
我添加了一些样板代码以使我的代码片段编译,因此您需要根据需要改变它。
`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
}
}