通用核心数据获取请求

时间:2017-03-20 23:04:37

标签: swift generics core-data

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

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

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<NSFetchRequestResult>类型的值转换为指定类型NSFetchRequest<T>

建议的解决方案甚至更奇怪,因为当我进行投射时所有内容都会编译:

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

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

  

由于未捕获的异常而终止应用   &#39; NSInvalidArgumentException&#39;,原因:&#39; executeFetchRequest:错误:   <null>不是有效的NSFetchRequest。&#39;

我做错了什么,或者这些只是目前无法超越的一些斯威夫特的限制?

1 个答案:

答案 0 :(得分:0)

这里的问题是fetchRequest()是自动生成的帮助器函数,仅对您的NSManagedObject子类可用。它不适用于您的通用类型。因此,不必使用该函数,而必须将其实现与此类通用类型一起使用

替换此行

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

与此

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