You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,而非固定100
  • cellForRowAt读取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 16:31:04