调用setValuesForKeys报错:类对key type不支持键值编码
解决setValue:forUndefinedKey:的KVC兼容问题
这问题我做项目时也踩过!核心原因就是KVC找不到接口返回JSON里的type字段对应的类属性,咱们一步步来解决:
1. 快速规避崩溃:忽略未知Key
你的ResumeCategory类只定义了name和resumes,但接口返回的JSON里存在type字段,KVC尝试给这个Key赋值却找不到对应属性,直接触发报错。最快的解决方式是重写setValue(_:forUndefinedKey:)方法,让系统忽略未定义的Key:
class ResumeCategory: NSObject { var name: String? var resumes: [Resume]? // 重写方法,忽略未定义的Key override func setValue(_ value: Any?, forUndefinedKey key: String) { // 啥也不做,直接返回即可避免崩溃 return } static func getJSON() { let urlString = "https://api.letsbuildthatapp.com/appstore/featured" // ...你的网络请求代码 } }
2. 补全对应属性(如果需要用到type字段)
如果业务逻辑里确实需要使用JSON中的type值,直接在类里添加同名属性就能让KVC自动匹配:
class ResumeCategory: NSObject { var name: String? var resumes: [Resume]? var type: String? // 新增与JSON字段同名的属性 static func getJSON() { let urlString = "https://api.letsbuildthatapp.com/appstore/featured" // ...你的网络请求代码 } }
3. 注意自定义数组的KVC解析坑
另外要提醒你:resumes是[Resume]自定义对象数组,KVC默认不会自动把JSON数组转换成Resume实例数组,你需要手动处理这部分逻辑。比如解析数据时:
// 假设你已拿到JSON字典jsonDict: [String: Any] let category = ResumeCategory() category.setValuesForKeys(jsonDict) // 手动解析resumes数组 if let resumesJSON = jsonDict["resumes"] as? [[String: Any]] { category.resumes = resumesJSON.compactMap { resumeJSON in let resume = Resume() resume.setValuesForKeys(resumeJSON) return resume } }
别忘了给Resume类也重写setValue(_:forUndefinedKey:),避免它也出现同样的Key错误。
4. 推荐:用手动解析替代KVC(更安全可控)
KVC虽然省事,但接口字段一旦变动就容易崩溃,推荐用手动解析的方式,代码更清晰也更易维护:
class ResumeCategory: NSObject { var name: String? var resumes: [Resume]? var type: String? // 如果需要的话 // 自定义字典初始化方法 init?(dictionary: [String: Any]) { super.init() self.name = dictionary["name"] as? String self.type = dictionary["type"] as? String // 手动解析resumes数组 if let resumesJSON = dictionary["resumes"] as? [[String: Any]] { self.resumes = resumesJSON.compactMap { Resume(dictionary: $0) } } } static func getJSON() { let urlString = "https://api.letsbuildthatapp.com/appstore/featured" // ...网络请求后,拿到JSON字典调用init(dictionary:)初始化 } } // Resume类也用同样方式处理 class Resume: NSObject { // 你的Resume属性,比如title、date等 var title: String? init?(dictionary: [String: Any]) { super.init() self.title = dictionary["title"] as? String // 其他属性依次解析 } }
内容的提问来源于stack exchange,提问作者Ishmael
相关产品推荐
相关产品推荐

