如何在 KeyPath 中使用 "Self.attr"?

How to use "Self.attr" in a KeyPath?

我试图在协议扩展中使用 "Self.displayOrder",但它引发了以下错误 "Thread 1: Fatal error: Could not extract a String from 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 运行时,并允许从 Swift KeyPath 转换为 [=13= 所需的字符串].

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