我的打印语句显示该函数在大约 15 秒内被调用了 4771 次,显然导致了崩溃。
这是函数:
override func collectionView(_ collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAt indexPath: IndexPath!) -> JSQMessageAvatarImageDataSource! {
count += 1
print("\n\nAvatar func called \(count)\n")
let databaseRef = FIRDatabase.database().reference()
let message = messages[indexPath.item]
let placeHolderImage = UIImage(named: "Logo")
let avatarImage = JSQMessagesAvatarImage(avatarImage: nil, highlightedImage: nil, placeholderImage: placeHolderImage)
if let messageID = message.senderId {
// Check cache for avatar
if imageCache.object(forKey: messageID as NSString) != nil {
DispatchQueue.main.async {
avatarImage!.avatarImage = imageCache.object(forKey: messageID as NSString)
avatarImage!.avatarHighlightedImage = imageCache.object(forKey: messageID as NSString)
self.collectionView.reloadData()
}
} else {
// If avatar isn't cached, fire off a new download
databaseRef.child("users").child(messageID).observe(.value, with: { (snapshot) in
if let profilePic = (snapshot.value as AnyObject!)!["profilePicture"] as! String! {
let profilePicURL: URL = URL(string: profilePic)!
Alamofire.request(profilePicURL)
.responseImage { response in
if let downloadedImage = response.result.value {
imageCache.setObject(downloadedImage, forKey: message.senderId as NSString)
DispatchQueue.main.async {
avatarImage!.avatarImage = imageCache.object(forKey: message.senderId as NSString)
avatarImage!.avatarHighlightedImage = imageCache.object(forKey: message.senderId as NSString)
self.collectionView.reloadData()
}
}
}
}
})
}
}
return avatarImage
}
是什么导致了循环?无论如何,只有一个用户(我)可以获得头像。我对编程有些陌生,正在尝试弄清楚如何使用缓存...我使用此功能的目的是检查用户的头像是否已缓存,如果已缓存,请使用它。如果没有,请从 Firebase 重新下载。但我显然搞砸了 - 我如何编写它才能有效地检查缓存和/或下载图像,并且不会陷入循环?
最佳答案
你在你的函数中调用了reloadData
,这将导致这个函数被再次调用,它调用了reloadData
等等;你已经创建了一个无限循环。
如果您最初返回一个占位符然后随后从网络检索头像,您只需要重新加载任何内容。在这种情况下,重新加载整个 Collection View 是非常浪费的;您只需要重新加载受影响的项目:
override func collectionView(_ collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAt indexPath: IndexPath!) -> JSQMessageAvatarImageDataSource! {
count += 1
print("\n\nAvatar func called \(count)\n")
let databaseRef = FIRDatabase.database().reference()
let message = messages[indexPath.item]
let placeHolderImage = UIImage(named: "Logo")
let avatarImage = JSQMessagesAvatarImage(avatarImage: nil, highlightedImage: nil, placeholderImage: placeHolderImage)
if let messageID = message.senderId {
// Check cache for avatar
if let cacheObject = imageCache.object(forKey: messageID as NSString) {
avatarImage!.avatarImage = cacheObject
avatarImage!.avatarHighlightedImage = cacheObject
} else {
// If avatar isn't cached, fire off a new download
databaseRef.child("users").child(messageID).observe(.value, with: { (snapshot) in
if let profilePic = (snapshot.value as AnyObject!)!["profilePicture"] as! String! {
let profilePicURL: URL = URL(string: profilePic)!
Alamofire.request(profilePicURL)
.responseImage { response in
if let downloadedImage = response.result.value {
imageCache.setObject(downloadedImage, forKey: message.senderId as NSString)
DispatchQueue.main.async {
self.collectionView.reloadItems(at:[indexPath])
}
}
}
}
})
}
}
return avatarImage
}
关于ios - 为什么我下载头像的函数被调用了数千次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43667700/