如何为可以返回nil的NSPredicate创建一个惰性var

时间:2017-06-22 17:50:03

标签: swift core-data swift3 nspredicate

我有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然后没有返回任何记录。

我该如何做到这一点?

1 个答案:

答案 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
    }

}