iOS Swift:如何从嵌套数组结构的JSON中读取全部产品图片并展示
问题原因
- 你当前代码中给
Img1/Img2/Img3三个属性赋值时,全部调用了images.first取数组的第一张图,所以三个位置最终加载的都是同一张首图 - URLSession数据任务的回调是在后台线程执行,直接给UI属性赋值存在线程安全隐患,可能出现UI不更新或者崩溃的问题
- 代码中存在多处强制解包逻辑,遇到异常数据会直接触发崩溃
修复后代码
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { guard let detail = self.storyboard?.instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController else { return } let currentItem = arrdata[indexPath.row] // 基础属性赋值 detail.Name = currentItem.name detail.Name2 = currentItem.name detail.SH_desc = currentItem.categories.first?.type ?? "" detail.Desc = currentItem.description detail.Price = currentItem.price // 取首图给顶部Image属性 if let firstImgSrc = currentItem.images.first?.src, let url = URL(string: firstImgSrc) { URLSession.shared.dataTask(with: url) { data, _, error in guard let data = data, let image = UIImage(data: data), error == nil else { return } DispatchQueue.main.async { detail.Image = image } }.resume() } // 按索引取前三张图给底部三个图片位 let imgProperties = [\DetailViewController.Img1, \DetailViewController.Img2, \DetailViewController.Img3] for (index, property) in imgProperties.enumerated() { guard index < currentItem.images.count, let imgSrc = currentItem.images[index].src, let url = URL(string: imgSrc) else { continue } URLSession.shared.dataTask(with: url) { data, _, error in guard let data = data, let image = UIImage(data: data), error == nil else { return } DispatchQueue.main.async { detail[keyPath: property] = image } }.resume() } self.navigationController?.pushViewController(detail, animated: true) }
优化说明
- 按索引读取images数组中的对应图片,实现三个位置加载不同的图片
- 所有UI属性赋值都切换到主队列执行,保证线程安全
- 替换了强制解包逻辑,增加异常判断避免崩溃
- 用keypath的方式简化了三张图片的加载逻辑,减少重复代码
内容的提问来源于stack exchange,提问作者Ahana Chakraborty
相关产品推荐
相关产品推荐

