【问题标题】:Generic core data fetch request通用核心数据获取请求
【发布时间】:2017-03-20 23:04:36
【问题描述】:

我正在尝试为简单的核心数据获取创建某种通用包装器。

我想要实现的是,而不是编写多个看起来像这样的冗余方法:

func loadNSMOSubclass() -> [NSMOSubclass] {
    let fetchRequest: NSFetchRequest<NSMOSubclass> = NSMOSubclass.fetchRequest()
    do {
        let result = try mainContext.fetch(fetchRequest)
        return result
    }
    catch {
        return []
    }
}

我想我可以为此创建一个通用助手:

struct EntityLoader<T> where T: NSManagedObject {

   func loadEntity() -> [T] {
       let fetchRequest: NSFetchRequest<T> = T.fetchRequest()
       do {
           let mainContext = CoreDataState().mainContext
           let result = try mainContext.fetch(fetchRequest)
           return result
       }
       catch {
           return []
       }
    }
}

然而,此时编译器出现了一个奇怪的错误:

无法将NSFetchRequest&lt;NSFetchRequestResult&gt; 类型的值转换为指定类型NSFetchRequest&lt;T&gt;

建议的解决方案更奇怪,因为在我进行强制转换时所有内容都会编译:

let fetchRequest: NSFetchRequest<T> = T.fetchRequest() as! NSFetchRequest<T>

这可能很难看,但我可以忍受。但是,当我运行此代码时,我遇到了一个致命错误:

由于未捕获的异常而终止应用程序 'NSInvalidArgumentException',原因:'executeFetchRequest:错误: &lt;null&gt; 不是有效的 NSFetchRequest。'

是我做错了什么,还是这些只是 Swift 的一些目前无法超越的限制?

【问题讨论】:

标签: swift generics core-data


【解决方案1】:

这里的问题是fetchRequest() 是一个自动生成的辅助函数,它仅适用于您的NSManagedObject 子类。它不适用于您的泛型类型。因此,您不必使用该函数,而是必须像这样将它的实现与您的泛型类型一起使用,

替换这一行,

let fetchRequest: NSFetchRequest<T> = T.fetchRequest()

有了这个,

let fetchRequest: NSFetchRequest<T> = NSFetchRequest<T>(entityName: String(describing: T.self))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    • 2018-02-11
    • 2019-11-06
    • 2013-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多