Swift中Type 'HeroStruct.Type'无法遵循Decodable的解决办法
解决Type 'HeroStruct.Type' cannot conform to 'Decodable'错误及后续数据展示问题
核心错误原因
你解码时用了HeroStruct.Type或[HeroStruct].Type作为类型参数,这是错误写法。JSONDecoder.decode(_:from:)需要传入具体类型的元类型,应该用.self而非.Type。另外接口返回的是英雄数组,所以正确的解码类型是[HeroStruct].self。
完整修复步骤及代码
1. 修正getJsonData方法
- 替换错误的解码写法,改用
[HeroStruct].self - 补上
task.resume()启动网络请求(你之前漏掉了这一步,请求根本没执行) - 用可选绑定处理
data,避免强制解包崩溃 - 解码后将结果赋值给
hero数组,切回主线程刷新表格
修正后的getJsonData代码:
func getJsonData(completion: @escaping () -> () ) { guard let url = URL(string: "https://api.opendota.com/api/heroStats") else { print("无效的URL") completion() return } let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in if let error = error { print("请求错误:\(error.localizedDescription)") completion() return } guard let data = data else { print("未获取到数据") completion() return } do { let result = try JSONDecoder().decode([HeroStruct].self, from: data) // 切回主线程更新UI DispatchQueue.main.async { self?.hero = result self?.tableView.reloadData() completion() } } catch { print("解码错误:\(error)") completion() } } task.resume() // 启动请求 }
2. 修正TableView数据源方法
numberOfRowsInSection返回hero.count,而非固定100cellForRowAt读取hero数组数据填充到cell
修正后的TableView相关方法:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return hero.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil) let currentHero = hero[indexPath.row] cell.textLabel?.text = currentHero.localized_name cell.detailTextLabel?.text = "属性:\(currentHero.primary_attr) | 攻击类型:\(currentHero.attack_type)" cell.backgroundColor = .systemYellow return cell }
3. 触发网络请求
在viewDidLoad末尾添加调用,启动数据请求:
override func viewDidLoad() { super.viewDidLoad() // ... 原有代码 ... getJsonData { } }
其他说明
HeroStruct的定义完全正确,无需修改,它已经遵循Decodable协议,且属性名和接口返回的JSON字段完全匹配。
内容的提问来源于stack exchange,提问作者7mach
相关产品推荐
相关产品推荐

