将 NSFetchRequest<T> 转换为 NSFetchRequest<NSFetchRequestResult> 时出错,其中 T 是通用 NSManagedObject

Error casting NSFetchRequest<T> to NSFetchRequest<NSFetchRequestResult> where T is generic NSManagedObject

我想声明我是 Swift 的新手,我正在探索 CoreData 概念。我尝试使用 ToDo 列表应用程序进行测试,该应用程序在欢迎屏幕上显示用户创建的任务类别,单击任何类别后,用户将看到该组中的所有任务。我试图创建一个通用的 class 类似 ToDoListViewController<T: NSManagedObject> 的东西,并实现可用于两个视图控制器(CategoryViewControllerTaskViewController)的功能。在那个 class 中,我创建了一个函数 loadItems,它将 predicate 作为参数,并使用来自获取请求的项目填充页面。所以代码大致是这样的:

class ToDoListViewController<T: NSManagedObject>: UITableViewController {

    func loadItems(predicate: NSPredicate? = nil) {
        let request: NSFetchRequest<T> = T.fetchRequest()
        
        if predicate != nil {
                request.predicate = predicate!
            }
        
        do {
            let items = try context.fetch(request)
            // Do something
        } catch {
            print("Error fetching items from context \(error)")
        }
    }
}

问题是当我尝试编译时出现错误:

Cannot assign value of type NSFetchRequest<NSFetchRequestResult> to type NSFetchRequest<T>

分配 request 变量时。但是,如果我像这样强制将 NSFetchRequest<NSFetchRequestResult> 转换为 NSFetchRequest<T>

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

一切正常。既然 NSManagedObject 的文档明明是符合 NSFetchRequestResult 协议的,那为什么还要强制把 NSFetchRequest<NSFetchRequestResult> 强制转换为 NSFetchRequest<T>

您必须转换类型,因为 NSFetchRequest 的泛型类型被限制为 NSFetchRequestResult – 也可以是 NSDictionaryNSNumberNSManagedObjectID.

与其让通用类型更通用,我建议使用具有关联类型的协议,如所述