Swift 3中如何递增PFFile数组索引避免数组越界崩溃?
解决Parse Server PFFile可选类型导致的数组索引不匹配问题
这个问题我之前踩过一模一样的坑!核心问题就出在你把PFFile和其他数据拆成两个数组存储——当部分对象没有图片时,PFFile数组的长度必然会比填充TableView的数据数组短,直接用数据数组的索引去取PFFile,不出错才怪。下面是最稳妥的解决思路:
1. 用自定义模型封装所有数据(包括可选PFFile)
别再把数据拆成多个数组了,创建一个自定义结构体/类,把每个数据项的所有属性(包括可选的PFFile)都打包进去。这样每个模型对象对应TableView的一行,索引完全同步,根本不会有不匹配的问题。
举个Swift的例子(OC思路完全一致):
import Parse struct Post { let title: String let content: String let imageFile: PFFile? // 标记为可选类型,对应可能没有图片的情况 // 从PFObject解析成自定义模型 init(pfObject: PFObject) { self.title = pfObject["title"] as? String ?? "" self.content = pfObject["content"] as? String ?? "" self.imageFile = pfObject["image"] as? PFFile } }
2. 从Parse Server获取数据时,统一解析为模型数组
请求数据时,把每个返回的PFObject都转换成自定义的Post对象,然后放到同一个数组里。不管有没有图片,每个数据项都会被完整加入数组:
var posts: [Post] = [] func fetchPosts() { let query = PFQuery(className: "Posts") query.findObjectsInBackground { [weak self] objects, error in guard let objects = objects else { return } self?.posts = objects.map { Post(pfObject: $0) } self?.tableView.reloadData() } }
3. 在TableView代理方法中安全处理可选PFFile
现在posts数组的长度和TableView的行数完全一致,在cellForRowAt里直接取对应索引的模型,然后判断imageFile是否存在即可:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexPath) as! PostCell // 先做索引安全检查,双重保险 guard indexPath.row < posts.count else { cell.titleLabel.text = "加载失败" return cell } let post = posts[indexPath.row] // 填充其他非可选数据 cell.titleLabel.text = post.title cell.contentLabel.text = post.content // 处理图片:有则加载,无则显示占位图 if let imageFile = post.imageFile { imageFile.getDataInBackground { data, error in if let data = data, let image = UIImage(data: data) { cell.postImageView.image = image } else { cell.postImageView.image = UIImage(named: "placeholder") } } } else { cell.postImageView.image = UIImage(named: "placeholder") } return cell }
这样处理后,不管数据里有没有图片,TableView的数据源都是完全同步的,再也不会出现索引越界的问题啦!
内容的提问来源于stack exchange,提问作者Iam Wayne
相关产品推荐
相关产品推荐

