我正在尝试在协议扩展中使用"Self.displayOrder",但它引发了以下错误"线程 1:致命错误:无法从 KeyPath Swift.ReferenceWritableKeyPath 中提取字符串">
这是代码
protocol Listable where Self: NSManagedObject {
static func sortedFetchRequest() -> NSFetchRequest<Self>
var displayOrder: Int { get set }
}
extension Listable {
static func sortedFetchRequest() -> NSFetchRequest<Self> {
let req: NSFetchRequest<Self> = NSFetchRequest(entityName: String(describing: Self.self))
req.sortDescriptors = [NSSortDescriptor(keyPath: Self.displayOrder, ascending: true)]
return req
}
}
final class OwnerModel: NSManagedObject, Identifiable, Listable {
@NSManaged var displayOrder: Int
}
您需要用@objc
声明协议:
@objc protocol Listable where Self: NSManagedObject {
var displayOrder: Int { get set }
}
这将告诉编译器在处理密钥路径时使用 Objective-C 运行时,并允许从 SwiftKeyPath
转换为SortDescriptor
所需的字符串。
sortedFetchRequest
必须从协议定义中删除一个注意事项,因为协议中不可能实现协议要求的默认实现@onjc,因为默认实现是静态调度的,而@objc协议是动态调度的。不过,这并不妨碍你在 Swift 代码中使用默认实现。