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复用机制:
- 在
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() } }
- 修改
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
相关产品推荐
相关产品推荐

