ios - Swift 协议(protocol)泛型错误(ORM 实现)

标签 ios swift orm metaprogramming

我试图在 Couchbase Lite iOS 2.0 之上实现一个 ORM 层,现在它删除了 CBLModel api,这使得它有点难以使用。

我使用 Reflection lib 及其 Mappable 协议(protocol)(在以下代码中重命名为 ORMMappable)来简化映射 api。 这是错误消息:

let t = Self.cast_id_type(type: link, obj: value)

Cannot invoke 'cast_id_type' with an argument list of type '(type: ORMMappable.Type, obj: Any?)'

  1. Expected an argument list of type '(type: D.Type, obj: Any?)'

这是有问题的代码

typealias MappableDictionary = [String : Any]

class IDString<T:ORMMappable> : NSString{
    func load_object(){
    }
}

struct MapMeta{
    var ignores : [String] = []
    var mapping : [String:ORMMappable.Type] = [:]
}

protocol ORMMappable {
    var id : NSString {get set}
    static var _meta : MapMeta{get}
    init(dictionary: MappableDictionary) throws
}
extension ORMMappable {
    init() throws{
        try self.init(dictionary: [:] as MappableDictionary)
    }
    
    static func cast_id_type<D:ORMMappable>(type: D.Type,obj: Any?) -> IDString<D>?{
        if let o = obj as? IDString<D>{
            return o
        }
        return nil
    }
    
    init(dictionary: MappableDictionary) throws {
        self = try construct { property in
            let meta = Self._meta
            if let value = dictionary[property.key] {
                if let type = property.type as? ORMMappable.Type, let value = value as? MappableDictionary {
                    return try type.init(dictionary: value)
                }
                else if let link = meta.mapping[property.key]
                {
                    let t = Self.cast_id_type(type: link, obj: value)
                    print(link)
                    //return t
                    return nil
                }
                else {
                    return value
                }
            } else {
                return nil
                //throw Error.missingRequiredValue(key: property.key)
            }
        }
    }
}

使用示例是

struct TestObject : ORMMappable{
    static var _meta: MapMeta{
        return MapMeta(ignores: [], mapping: ["link_id":TestObject2.self])
    }
    
    var id : NSString
    var name : String?
    var age : Int?
    var link_id : IDString<TestObject2>?
}

IDString 是指向其他 ORMMappable 兼容类的链接的持有者,将 String(属性名称)映射到 ORMMappable 兼容类,cast_id_type 会检查映射并尝试从 value 指针强制转换为 StringID 对象。错误本身让我很困惑,

static func cast_id_type<D:ORMMappable>(type: D.Type,obj: Any?) -> IDString<D>?

D应该是一个ORMMappable兼容类,这里我给出的是一个[String:ORMMappable.Type]的值,但是却上升了ORMMappable.Type不是D.Type,这是怎么来的?

此外,我期待是否有更好的方法可以快速执行 ORM,目前代码确实可以处理动态对象创建,但是当涉及 ORM 关系时,它真的让我发疯,只是在寻找管理方法它以一种更简单、更易于管理的方式,目前看起来没有太多功能可以进行元编程,许多其他 ORM 库仍在使用 objc,这在动态实例创建或类检查方面更容易(但样板) .

非常感谢您的帮助,任何提示都将非常感激:)

最佳答案

删除所有泛型解决了问题,它不会在运行时环境中推断。

关于ios - Swift 协议(protocol)泛型错误(ORM 实现),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51753377/

相关文章:

python - 使用 PEP 435 兼容枚举的带有枚举的 SQLAlchemy 列产生表创建错误

objective-c - CALayer是否保留CGColor对象?

ios - 将应用内购买收据数据发送到我的服务器

ios - livereload 导致应用程序在启动画面上停止(连续加载轮)-Ionic

ios - RTL 图像不会在 UITableViewCell 中翻转

swift - UITapGestureRecognizer : Modal View is overlapped by another view

javascript - 通过sequelize返回父属性

sql - django-SQL用户ORM指南?

iOS 有一种方法可以将本地化字符串分配给 IB/ Storyboard中的 UILabel

ios - 滚动 UITableView 与渐变困惑