需要通用的 FetchedResultsController 构建器 (Swift)
Need generic FetchedResultsController builder (Swift)
我创建了一个构建 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")
但我收到此错误:
"Cannot convert value of type 'ObjectName.Type' to expected argument type 'NSManagedObject'".
然而,ObjectName
是 NSManagedObject
的 class 名称。我试过自己
但最终我只是一直在追逐错误。
您的函数声明并不意味着完全您认为的那样。
private func buildFRC<T:NSManagedObject>(entity: T, sortKey: String) -> NSFetchedResultsController<T>?
这意味着 T
必须是 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
将导致所有那些先前获取的对象变得无效。使用它们会使您的应用程序崩溃。
我创建了一个构建 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")
但我收到此错误:
"Cannot convert value of type 'ObjectName.Type' to expected argument type 'NSManagedObject'".
然而,ObjectName
是 NSManagedObject
的 class 名称。我试过自己
但最终我只是一直在追逐错误。
您的函数声明并不意味着完全您认为的那样。
private func buildFRC<T:NSManagedObject>(entity: T, sortKey: String) -> NSFetchedResultsController<T>?
这意味着 T
必须是 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
将导致所有那些先前获取的对象变得无效。使用它们会使您的应用程序崩溃。