1

我创建了一个构建 frc 的方法:

private func buildFRC<T:NSManagedObject>(entity: T, sortKey: String) 
    -> NSFetchedResultsController<T>? {

    let fetchRequest: NSFetchRequest = T.fetchRequest()
    let sortDescriptor1 = NSSortDescriptor(key: sortKey, ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor1]

    searchContext.reset()

    var frc: NSFetchedResultsController<T>? =
        NSFetchedResultsController<T>(
        fetchRequest:            fetchRequest as! NSFetchRequest<T>,
        managedObjectContext:   searchContext,
        sectionNameKeyPath:     nil,   
        cacheName:              nil)   
    frc!.delegate = self                

    try? frc!.performFetch()
    return frc
}

我想在闭包中调用这样的东西:

self.frc = self.buildFRC(entity: ObjectName, sortKey: "trackName")

但我收到此错误:

“无法将 'ObjectName.Type' 类型的值转换为预期的参数类型 'NSManagedObject'”。

然而,ObjectName是一个NSManagedObject. 我尝试过自己,但最终我只是不停地追逐错误。

4

1 回答 1

2

您的函数声明并不完全符合您的想法。

private func buildFRC<T:NSManagedObject>(entity: T, sortKey: String) -> NSFetchedResultsController<T>? 

这意味着 thatT必须是 的子类NSManagedObject,并且第一个参数必须是T 的实例。当你这样称呼它时

self.frc = self.buildFRC(entity: ObjectName, sortKey: "trackName")

...当您的声明需要一个实例时,您将子类作为第一个参数传递。

这并不难解决,因为您不需要将T其作为参数包含在内。一般来说,Swift 泛型不需要你将类型作为参数传递——类型来自于函数的使用方式。删除该参数并将声明重写为

private func buildFRC<T:NSManagedObject>(sortKey: String) -> NSFetchedResultsController<T>? {

然后用类似的东西调用函数

self.frc: NSFetchedResultsController<ObjectName>? = self.buildFRC(sortKey: "trackName")

Swift 会在该调用中找出T表示,并且代码将起作用。ObjectName

顺便说一句,您的呼叫searchContext.reset()有点危险,可能不需要。如果您从上下文中获取一些对象,然后稍后调用此函数,这reset将导致所有先前获取的对象变得无效。使用它们会使您的应用程序崩溃。

于 2018-11-16T23:50:27.427 回答