Firebase 和 Alamofire Url TableViewCell 图像加载问题 Swift 4

Posted

技术标签:

【中文标题】Firebase 和 Alamofire Url TableViewCell 图像加载问题 Swift 4【英文标题】:Firebase & Alamofire Url TableViewCell image load Issue Swift 4 【发布时间】:2018-04-24 07:56:07 【问题描述】:

我正在使用Alamofire 将图像设置到tableViewCell

let messageImage = cell?.viewWithTag(6) as! UIImageView
messageImage.image = nil
messageImage.af_setImage(withURL: photoUrl! as URL)

return cell

我正在使用 Firebase 将每个单元格项附加到一个数组中:

ref.child("messages").child(ticker.current).queryOrderedByKey().observe(.childAdded, with: snapshot in

            let snapDict = snapshot.value as? NSDictionary
            let photoUrl = snapDict?["photo_url"] as? String ?? ""

            messageArray.insert(messageCellStruct(photoUrl: photoUrl), at: 0)
         )

然后我将 Same Exact URL 上的图片更新为 FirebaseStorage

当我重新调用TableViewCell 所在的单元格ViewController 时,前几个单元格上的图像没有改变。但是当我滚动到旧单元格时,图像会更新:

messageArray.removeAll()
tableView.reload()

如果我重新构建应用程序,所有单元格图像都是应有的样子。

我假设这是因为观察者错误或我没有删除观察者。我真的不知道。

1.) 单元格共享完全相同的 URL,只是更改了数据。

2.) 它似乎只在尚未加载(或分配)单元格时才起作用。

3.) 在我重建并运行应用程序后,它工作得非常好。

也许我需要清除 Alamofire 缓存?

【问题讨论】:

【参考方案1】:

messageImage.af_setImage(withURL: photoUrl! as URL)中设置图像之前,听起来您需要将旧图像设置为零。

Cell 应该在重新使用之前进行清理:Apple -PrepareForReuse 但 Apple 也表示:

出于性能原因,您应该只重置单元格的属性 与内容无关的内容,例如 alpha、编辑和 选择状态。表视图的委托 tableView(_:cellForRowAt:) 应始终重置所有内容 重复使用一个单元格。

这基本上意味着您不应该在prepareForReuse 中将您的imageView 的图像设置为零,但是如果您对单元格进行子类化,您可以在子类中创建一个函数并在cellForRowAtIndePath 中调用它,然后再运行messageImage.af_setImage(withURL: photoUrl! as URL)。下面的例子:

为单元格创建子类并将其命名为 MyCustomCell

class MyCustomCell: UITableViewCell 

@IBOutlet weak var messageImage: UIImageView!

    func setImageToNil()
        messageImage.image = nil
        // I don't use AlamoFire and don't know anything about it but if they have something to set the imageView's image to nil you can also try using that instead
    

在你的 tableView 的 cellForRowAtIndexPath 中投射单元格,然后在运行 messageImage.af_setImage 之前调用 setImageToNil()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

     // 0. cast the cell as MyCustomCell
     let cell = tableView.dequeueReusableCell(withIdentifier: "MyCustomCell", for: indexPath) as! MyCustomCell

     // 1. call the setImageToNil() method and whatever image is inside messageImage will get set to nil every time the cell is reused
     cell.setImageToNil()

     // 2. the new image should always appear because the old image was set to nil
     cell.messageImage.af_setImage(withURL: photoUrl! as URL)

     return cell

【讨论】:

更新我已经这样做了。我想不通。当我向 Firebase 发布更新时它会发生变化,但不会更改旧图像。 我认为 Alamofire 会在本地缓存图像,这可能是原因。我需要做更多的研究。 可能 alamofire 正在缓存并以某种方式显示旧图像???你试过 SDWebImage 吗?效果很好cocoapods.org/pods/SDWebImage 试试这个 SO q&a,其他人也有同样的问题:***.com/q/33467263/4833705 我觉得我会遇到同样的问题,它将其存储在本地。我想我发现了我的问题。我需要清除缓存。【参考方案2】:

Alamofire在本地保存图片缓存。

因为我将数据更改为 完全相同的 URL,所以我不得不删除缓存。

 UIImageView.af_sharedImageDownloader.imageCache?.removeAllImages()

 UIImageView.af_sharedImageDownloader.sessionManager.session.configuration.urlCache?.removeAllCachedResponses()

【讨论】:

以上是关于Firebase 和 Alamofire Url TableViewCell 图像加载问题 Swift 4的主要内容,如果未能解决你的问题,请参考以下文章

UIButton 点击​​,Alamofire POST 调用,不执行 Segue 并成功登录 Firebase

如何使用 Alamofire 的 RequestAdapter 将 firebase ID 令牌设置为全局标头?

将带有完成处理程序的 Firebase IdToken 添加到每个 AlamoFire 请求

Alamofire:在特定 URL 和设备上请求超时

如何在swift中使用alamofire和swiftyjson解析分页url?

使用 django API 和 Alamofire 请求失败