if let toID = message.chatPartnerId() {
firebaseReference.child(toID).observeSingleEvent(of: .value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: Any] {
cell.nameLabel.text = dictionary["displayname"] as? String
let pic = dictionary["pictureURL"] as! String
print("THIS IS THE URL FOR EACH DISPLAYNAME")
print(dictionary["displayname"] as? String)
print(pic)
if let imageFromCache = MainPageVC.imageCache.object(forKey: pic as NSString) {
cell.pictureLabel.image = imageFromCache
} else {
let requested = URLRequest(url: URL(string: pic )!)
URLSession.shared.dataTask(with: requested) {data, response, err in
if err != nil {
print(err)
} else {
DispatchQueue.main.async {
let imageToCache = UIImage(data: data!)
MainPageVC.imageCache.setObject(imageToCache!, forKey: pic as NSString)
//cell.pictureLabel.image = nil
cell.pictureLabel.image = imageToCache
}
}
}.resume()
}
}
})
}
return cell
}
我在我的cellForRowAtIndexPath
中运行此代码,并且我收到了大量非常糟糕的行为。我也在其他页面上获得类似的行为,但由于某种原因,这段代码具有大约90%的一致性,会返回不正确的单元格信息。
我在错误的地方使用了大量重复的图片,displaynames
但是当我实际点击某个人时,我的详细信息页面每次都会显示正确的信息。该代码是典型的didSelectRowAtIndexPath
并传递此人。
我不明白为什么在这个页面的初始加载时,所有信息都被搞砸了,但是如果我点击某人然后回来,整个tableview
都有正确的名字和图片。如果我从屏幕上滚动一个单元格然后返回它,名称/图片也会修复。
我在我的应用程序中得到了这种行为,同时我看到缓存/加载在各处完成。是因为我在cellForRowAtIndexPath
中运行代码吗?我看到的唯一区别是我在那里运行它,而不是在我的Person类中创建一个函数来配置单元格并像这样运行它。我不明白为什么会有所不同,因为我知道在cellforRowAtIndexpath
内运行一个函数与将相同的代码复制粘贴到那里相同?
有任何想法/建议吗?
编辑:当我运行以下代码时,我的情况非常相似:
self.PersonalSearchesList = self.PersonalSearchesList.sorted{ $0.users > $1.users }
self.tableView.reloadData()
我在重新加载数据之前对数组进行排序。信息有时首先加载不正确,但是一旦我将屏幕上的单元格滚动出来然后再回到它,它总是会自行纠正。
答案 0 :(得分:1)
如果您使用swift 3,这里有一些方便的功能,允许您从URL将图像保存到您的apps目录,然后从应用程序的任何位置访问它:
func saveCurrentUserImage(toDirectory urlString:String?) {
if urlString != nil {
let imgURL: URL = URL(string: urlString!)!
let request: URLRequest = URLRequest(url: imgURL)
let session = URLSession.shared
let task = session.dataTask(with: request, completionHandler: {
(data, response, error) -> Void in
if (error == nil && data != nil) {
func display_image() {
let userImage = UIImage(data: data!)
if let userImageData = UIImagePNGRepresentation(userImage!) {
let filename = self.getDocumentsDirectory().appendingPathComponent("userImage")
try? userImageData.write(to: URL(fileURLWithPath: filename), options: [.atomic])
}
}
DispatchQueue.main.async(execute: display_image)
}
})
task.resume()
}
}
然后使用以下任意视图控制器访问它:
extension UIViewController {
func getImage(withName name: String) -> UIImage {
let readPath = getDocumentsDirectory().appendingPathComponent(name)
let image = UIImage(contentsOfFile: readPath)
return image!
}
}
最后这样称呼它:
cell.pictureLabel.image = getImage(withName: "userImage")
如果您可以在运行saveCurrentUserImage
之前运行cellForRowAtIndexPath
功能,那么您可以在尝试下载之前检查目录中的照片是否为nil。当页面最初加载时,您可能会遇到有趣的行为,因为您有多个网络调用同时进行。我不建议在cellForRowAtIndexPath
中进行任何网络呼叫,因为每次重新初始化小区时,它都会为每个小区进行网络呼叫。
希望它有所帮助!
编辑:这种图像保存和检索方法适用于您想要保留的图像。如果你想从内存中删除它们,你必须从目录中删除它们。