在将异步图像加载到UITableViewCell后滚动时,Swift图像会更改为错误的图像
我正在尝试在FriendsTableView(UITableView)单元格中异步加载图片。图像加载正常,但是当我滚动表格时,图像会改变几次,错误的图像会被分配给错误的单元格。
I'm trying to async load pictures inside my FriendsTableView (UITableView) cell. The images load fine but when I'll scroll the table the images will change a few times and wrong images are getting assigned to wrong cells.
我已经尝试了我在StackOverflow中找到的所有方法,包括在raw中添加一个标签然后检查它但是没有用。我还要验证应该使用indexPath更新的单元格并检查单元格是否存在。所以我不知道为什么会发生这种情况。
I've tried all methods I could find in StackOverflow including adding a tag to the raw and then checking it but that didn't work. I'm also verifying the cell that should update with indexPath and check if the cell exists. So I have no idea why this is happening.
这是我的代码:
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重用了单元格。以这种方式加载它们会导致异步请求在不同的时间返回并弄乱订单。
This is because UITableView reuses cells. Loading them in this way causes the async requests to return at different time and mess up the order.
我建议您使用一些库,这样可以让您的生活更轻松如Kingfisher 。它将为您下载和缓存图像。您也不必担心异步调用。
I suggest that you use some library which would make your life easier like Kingfisher. It will download and cache images for you. Also you wouldn't have to worry about async calls.
https://github.com/onevcat/Kingfisher
你的代码看起来像这样:
Your code with it would look something like this:
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
}