具有 NSObject 继承的泛型类,self.setValue(, forKey: ) 不起作用



我想使用 self.setValue(, forKey: ( 直接在NSObject中设置值,那次给我一个错误。

2018-03-08 17:36:36.723485+0530 BaseProject[20631:312969] *** 由于未捕获的异常"NSUnknownKeyException"而终止应用,原因:"[<_TtGC11BaseProject8DataRootCS_4Root_ 0x600000452840> setValue:forUndefinedKey:]:此类不符合键数据键值编码。

当我像var data: [T] = []一样使用通用 T 设置值时,应用程序崩溃了,我像var data: [Root] = []一样设置类名然后完美运行。

我的代码是

protocol AGMappable {
    init(with responseDict: [String: AnyObject])
}

我的模型类是

class Root: NSObject, AGMappable {
    var avatar: String = ""
    var id: Int = 0
    var first_name: String = ""
    var last_name: String = ""
    required init(with responseDict: [String: AnyObject]) {
        super.init()
        avatar = responseDict["avatar"] as? String ?? ""
    }
}

使用 setValue(,forKey:( 设置一个值

class DataRoot<T: AGMappable>: NSObject, AGMappable{
    var page: Int = 0
    var per_page: Int = 0
    var total: Int = 0
    var total_pages: Int = 0
    var data: [T] = []
    required init(with responseDict: [String: AnyObject]){
        super.init()
        if let datastr = responseDict["data"] as? [[String : AnyObject]] {
            var temp: [T] = []
            for v in datastr {
                temp.append(T(with: v as [String: AnyObject]))
            }
            self.setValue(temp, forKey: "data") // Here error
        }
    }
}

setValue(_:forKey:)只能使用@objc属性,因为它依赖于只有@objc属性才具有的运行时功能。Swift 4 改变了类成员对 Objective-C 的使用方式:默认情况下它们不再可用,因此您需要将类声明为 @objcMembers ,或者单独添加@objc到需要向 Objective-C 公开的每个成员。

但是,在您的情况下,由于类是泛型类,因此无法将类导出到 Objective-C,因此您需要将data声明为 @objc var data: [T] = []dynamic var data: [T] = []

你可以这样重写它

    let datastr = responseDict["data"] as? [[String : Any]]
    self.data = datastr?.map {
        T(with: $0)
    } ?? [T]()