我试图异步加载我的FriendsTableView(UITableView)单元内的图片。图像加载正常,但是当我滚动表格时,图像将更改几次,并且错误的图像被分配给错误的单元格。
我尝试了所有可以在StackOverflow中找到的方法,包括将标签添加到原始文件,然后检查它,但是那没有用。我还在验证应使用indexPath更新的单元,并检查该单元是否存在。所以我不知道为什么会这样。
这是我的代码:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("friendCell", forIndexPath: indexPath) as! FriendTableViewCell var avatar_url: NSURL let friend = sortedFriends[indexPath.row] //Style the cell image to be round cell.friendAvatar.layer.cornerRadius = 36 cell.friendAvatar.layer.masksToBounds = true //Load friend photo asyncronisly avatar_url = NSURL(string: String(friend["friend_photo_url"]))! if avatar_url != "" { getDataFromUrl(avatar_url) { (data, response, error) in dispatch_async(dispatch_get_main_queue()) { () -> Void in guard let data = data where error == nil else { return } let thisCell = tableView.cellForRowAtIndexPath(indexPath) if (thisCell) != nil { let updateCell = thisCell as! FriendTableViewCell updateCell.friendAvatar.image = UIImage(data: data) } } } } cell.friendNameLabel.text = friend["friend_name"].string cell.friendHealthPoints.text = String(friend["friend_health_points"]) return cell }
这是因为UITableView重用了单元格。以这种方式加载它们会导致异步请求在不同的时间返回并弄乱顺序。
我建议您使用一些类似于Kingfisher的图书馆,这将使您的生活更轻松。它将为您下载和缓存图像。同样,您也不必担心异步调用。
https://github.com/onevcat/Kingfisher
您的代码如下所示:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("friendCell", forIndexPath: indexPath) as! FriendTableViewCell var avatar_url: NSURL let friend = sortedFriends[indexPath.row] //Style the cell image to be round cell.friendAvatar.layer.cornerRadius = 36 cell.friendAvatar.layer.masksToBounds = true //Load friend photo asyncronisly avatar_url = NSURL(string: String(friend["friend_photo_url"]))! if avatar_url != "" { cell.friendAvatar.kf_setImageWithURL(avatar_url) } cell.friendNameLabel.text = friend["friend_name"].string cell.friendHealthPoints.text = String(friend["friend_health_points"]) return cell }