加载图像时UITableViewCell中的偶发行为

加载图像时UITableViewCell中的偶发行为,uitableview,swift3,alamofireimage,Uitableview,Swift3,Alamofireimage,我有一个表视图,可以显示注释。每个注释都包括一个标签和一个显示作者配置文件图像的UIImage。加载表格时,图像的显示方式没有模式。有时它们装载得很好。其他时候,会出现占位符图像,并且该图像根本不会加载。如果我滚动,行为会发生变化。我正在使用AlamofireImage 经过一些研究后,我发现了这篇文章,建议打电话给 self.tableView.beginUpdates() self.tableView.endUpdates() 在AlamofireImage的完成处理程序中。这根本没有效果

我有一个表视图,可以显示注释。每个注释都包括一个标签和一个显示作者配置文件图像的
UIImage
。加载表格时,图像的显示方式没有模式。有时它们装载得很好。其他时候,会出现占位符图像,并且该图像根本不会加载。如果我滚动,行为会发生变化。我正在使用
AlamofireImage

经过一些研究后,我发现了这篇文章,建议打电话给

self.tableView.beginUpdates()
self.tableView.endUpdates()
在AlamofireImage的完成处理程序中。这根本没有效果

这是我的原始代码:

func tableView(_ tableView: UITableView, cellForRowAt.....{
...
    let myURL = Comment.profileImageURL
            if Comment.profileImageURL != nil {
                profileImage.af_setImage(withURL: myURL!, placeholderImage: #imageLiteral(resourceName: "Profile Image"))
            } else {
                profileImage.image = UIImage(named: "Profile Image")
            }
以下是基于(第页最后一个答案)的更新:

==编辑====

添加更多信息,希望能有所帮助: 我已尝试按以下建议设置
profileImage.image=nil
。我还取消了
prepareforeuse()
中的下载,建议如下,但没有效果

在调用映像之前,我正在
UIImageView

profileImage.layer.cornerRadius = profileImage.bounds.size.width / 2
profileImage.clipsToBounds = true
profileImage.layer.borderWidth = 2
profileImage.layer.borderColor = UIColor(red:222/255.0, green:225/255.0, blue:227/255.0, alpha: 1.0).cgColor
以下是XCode中的imageView设置:

最后是问题本身。大约50%的时间我在视图之间来回移动或滚动,占位符图像出现在实际图像的位置。事实上占位符通常在第一次加载时出现

==编辑#2===

我正试着听从艾希礼·米尔斯的第二个建议。我在AlamoFileImage的完成处理程序中检查图像URL,结果是奇数。我刚刚加载了表视图。所有图像加载良好,如下所示:

当完成处理程序启动时,我打印出图像URL,它看起来很好:

我完成了 可选() 我完成了 可选() 我完成了 可选() 我完成了 可选()

使用导航栏,我退出,然后重新加载,图像都是占位符图像,如图所示:

打印件如下:

我的成绩是零 我的成绩是零 我的成绩是零

最后,这是加载图像和完成处理程序的代码:

 let myURL = Comment.profileImageURL
        if Comment.profileImageURL != nil {
           // profileImage.af_setImage(withURL: myURL!, placeholderImage: #imageLiteral(resourceName: "Profile Image"))
            profileImage.af_setImage(
                withURL: myURL!,
                placeholderImage: #imageLiteral(resourceName: "Profile Image"),
                filter: nil,
                completion:{ image in
                    print("I'm in completion")
                    print(image.response?.url)
                    self.setNeedsLayout()
                    self.layoutIfNeeded()
            })

        } else {
            profileImage.image = UIImage(named: "Profile Image")
        }

在这一点上,我已经尝试了一切。请提供帮助。

UITableViewController
重用单元格。为了防止旧图像在尚未完全加载的单元格中重新出现,请在加载前将单元格的图像设置为
nil

cell.profileImage.image = nil

let myURL = comment.profileImageURL

if comment.profileImageURL != nil {
    [...]
} else {
    cell.profileImage.image = UIImage(named: "Profile Image")
}

如果将图像中显示的每个单元格从屏幕上滚下,则可以重复使用。使用
af_setImage
将获取图像,并在收到响应时显示它,但此时该单元格可能会被重用,并尝试在不同的URL上显示图像

您可以通过两种方式处理此问题,但首先要做的是向单元格中添加
Comment
属性,并在那里而不是在视图控制器中处理下载(您可能会发现将所有的
IBOutlet
属性
fileprivate
都设置为私有有助于实现这一点-它可以确保您无法从视图控制器更新单元格的UI)

1) 重新使用单元时取消下载请求

override func prepareForResuse() {
    profileImage.af_cancelImageRequest
}
这将阻止返回对上一个URL的响应,但意味着图像不会被下载

2) 检查响应所针对的URL是否是您期望的URL

var requestedURL: URL?
var comment: Comment? {
    didSet {
        if let myURL = Comment.profileImageURL {
            requestedURL = myURL

            // Fetch image from URL and when response is received, 
            // check self.myURL == response.url

        } else {
            profileImage.image = UIImage(named: "Profile Image")
        }
    }
}

这样,即使未显示图像,图像仍将被下载。

4kman,谢谢您的建议。我进行了测试,遗憾的是,这并没有解决问题,尽管它似乎改善了情况。当图像确实可用(需要下载)时,我仍然会得到占位符图像。我试图在这里遵循您的解决方案。首先,在cellForRowAt中,我有一个configureCell()函数,它调用一个UITableViewCell子类,我在其中配置单元格。你建议在哪里打电话给prepareForReuse?就在调用configureCell之前?
prepareforeuse
是一个
UITableViewCell
方法,每次重新使用该单元格时都会自动调用该方法。你自己也不这么说,艾希礼,我以前已经做过准备了。我不清楚你的第二个建议。当我将comment对象传递给configureCell()时,我得到了所需的profileImageURL(comment.profileImageURL.),因此,当AlamoFileImage完成下载时,我应该将所需的URL与返回的URL进行比较。我是在阿拉莫的完成处理器里做的吗?如果它们不一样,那么会发生什么?还有一个观察结果。当tableView首次加载时,只有两条注释可见。即使不滚动,配置文件图像通常也不会显示。占位符图像可以。如果我移动到上一个视图并再次返回,它们将显示。非常奇怪,艾希礼。我正在按照您的建议从完成处理程序打印URL。出现问题时,图像url为零。我不清楚如何进行。你能看一下这篇文章的第二部分吗?谢谢
var requestedURL: URL?
var comment: Comment? {
    didSet {
        if let myURL = Comment.profileImageURL {
            requestedURL = myURL

            // Fetch image from URL and when response is received, 
            // check self.myURL == response.url

        } else {
            profileImage.image = UIImage(named: "Profile Image")
        }
    }
}