具有 NSObject 继承的泛型类,self.setValue(, forKey:) 不起作用
Posted
技术标签:
【中文标题】具有 NSObject 继承的泛型类,self.setValue(, forKey:) 不起作用【英文标题】:Generic Class with NSObject inheritance, self.setValue(, forKey: ) not work 【发布时间】:2018-03-08 12:39:49 【问题描述】:我想使用 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
【问题讨论】:
为了更好地理解问题尝试使用正确的方法并查看错误setValue(temp, forKey: #keyPath(data))
【参考方案1】:
setValue(_:forKey:)
只能与 @objc
属性一起使用,因为它依赖于只有 @objc
属性具有的运行时功能。 Swift 4 改变了类成员对 Objective-C 可用的方式:默认情况下它们不再可用,因此您需要将类声明为 @objcMembers
,或者将 @objc
单独添加到您需要暴露给 Objective 的每个成员-C。
但是,在您的情况下,由于该类是通用类,因此该类无法导出到 Objective-C,因此您需要将 data
声明为 @objc var data: [T] = []
或 dynamic var data: [T] = []
【讨论】:
【参考方案2】:你可以这样重写
let datastr = responseDict["data"] as? [[String : Any]]
self.data = datastr?.map
T(with: $0)
?? [T]()
【讨论】:
我的要求是使用 self.setValue(,forKey:) 赋值 你可以使用keyPaths吗?像这样self[keyPath: \DataRoot.data] = temp
以上是关于具有 NSObject 继承的泛型类,self.setValue(, forKey:) 不起作用的主要内容,如果未能解决你的问题,请参考以下文章