ios - 为什么我下载头像的函数被调用了数千次?

标签 ios swift

我的打印语句显示该函数在大约 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/

相关文章:

ios - 从现有的 tableView 数据源和 Controller 创建一个 collectionView

ios - 为什么即使在 Storyboard中嵌入导航 Controller 并使用 push segue 后,我的导航 Controller 仍为零?

arrays - 更好的 Swift 数组排序方法?

ios - 强制 iOS CloudKit 同步更新,将所有记录下载到本地设备

ios - 将缩小 View 的图像与 subview 中保持原始大小的图像合并

ios - iOS中使用glsl将yv12转rgb,附结果图

iphone - 从底部加载 UITableView

ios - 火力地堡, swift : Retrieving only those `autoID` node's which have a specific key

ios - 获取 CollectionView IOS 中的列数

ios - 在显示键盘后离开应用程序时出现快照错误(需要 afterScreenUpdates :YES)