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

时间:2018-03-08 12:39:50

标签: ios swift generics nsobject

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

  

2018-03-08 17:36:36.723485 + 0530 BaseProject [20631:312969] ***由于未捕获的异常'NSUnknownKeyException'终止应用程序,原因:'[< _TtGC11BaseProject8DataRootCS_4Root_0x600000452840> setValue:forUndefinedKey:]:此类不是密钥数据的密钥值编码。'

当我使用像var data: [T] = []这样的Generic 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
        }
    }
}

2 个答案:

答案 0 :(得分:0)

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

但是,在您的情况下,由于这是一个通用的类,因此无法将类导出到Objective-C,因此您需要将data声明为@objc var data: [T] = []或{{ 1}}

答案 1 :(得分:0)

你可以像这样重写它

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