2

我正在尝试在协议扩展中使用“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
}
4

1 回答 1

1

您需要使用以下方式声明协议@objc

@objc protocol Listable where Self: NSManagedObject {
    var displayOrder: Int { get set }
}

这将告诉编译器在处理 keypath 时使用 Objective-C 运行时,并允许从 Swift 转换KeyPathSortDescriptor.

必须从协议定义中删除一个注意事项,sortedFetchRequest因为协议要求的默认实现在协议中是不可能的,@onjc,因为默认实现是静态分派的,而@objc 协议是动态分派的。不过,这并不妨碍您在 Swift 代码中使用默认实现。

于 2020-01-18T09:30:46.220 回答