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

UITableView在模拟器不显示 代码无报错仅展示白屏如何解决?

问题根因

  • 你解析完JSON数据后,没有将接口返回的餐品列表赋值给控制器全局的meals数组,数组始终为空,TableView的行数返回0,自然不会渲染任何内容
  • 你将TableView刷新的回调放在了for循环内部,每遍历一条数据就触发一次刷新,属于无意义的频繁调用,会导致不必要的性能损耗
  • (非核心但不规范)viewDidLoad中你先设置了TableView代理再调用super.viewDidLoad(),不符合苹果推荐的调用顺序

修复步骤

1. 修正JSON解析逻辑

修改fetchJSON方法,完成数据解析后先给meals赋值,再统一触发一次TableView刷新,修正后的代码如下:

func fetchJSON(completed: @escaping () -> ()) {
    let jsonUrlString = "https://www.themealdb.com/api/json/v1/1/filter.php?c=Beef"
    guard let url = URL(string: jsonUrlString) else {
        print("invalid url string lel")
        return
    }
    print("Select a meal to make today!")
    URLSession.shared.dataTask(with: url) { data, response, error in
        guard let data = data else {
            return
        }
        do {
            let decoder = JSONDecoder()
            let mealDetailResponse = try decoder.decode(MealDetailResponse.self, from: data)
            // 给全局数组赋值,这步是之前缺失的核心逻辑
            self.meals = mealDetailResponse.meals
            // 可选:遍历打印验证数据是否正确
            for meal in self.meals {
                print("The Meal is \(meal.self)")
            }
            // 移到循环外部,主线程统一触发一次刷新
            DispatchQueue.main.async {
                completed()
            }
        } catch {
            print("解码错误:\(error)")
        }
    }.resume()
}

2. 调整viewDidLoad调用顺序(可选,规范写法)

override func viewDidLoad() {
    // 优先调用父类方法
    super.viewDidLoad()
    self.tableView.delegate = self
    self.tableView.dataSource = self
    fetchJSON {
        self.tableView.reloadData()
    }
}

可选优化建议(提升性能)

当前你每次返回cell都新建实例,滑动时会产生不必要的内存开销,推荐使用cell复用机制:

  1. 在viewDidLoad中注册cell复用标识符
override func viewDidLoad() {
    super.viewDidLoad()
    self.tableView.delegate = self
    self.tableView.dataSource = self
    // 注册cell
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "MealCell")
    fetchJSON {
        self.tableView.reloadData()
    }
}
  1. 修改cellForRowAt方法复用cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MealCell", for: indexPath)
    cell.textLabel?.text = meals[indexPath.row].strMeal.capitalized
    return cell
}

如果修改完成后依然无法正常显示,检查Meal和MealDetailResponse的属性名、类型是否和接口返回的JSON字段完全匹配即可。

内容的提问来源于stack exchange,提问作者Wen Love Howard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:06:06