如何防止tableView与异步方法崩溃?

时间:2017-02-28 16:00:09

标签: swift uitableview firebase firebase-realtime-database firebase-storage

我正在制作一个带有图片的tableView。图片是来自人们的个人资料图片,可以加入,离开并自己制作房间。在那个房间里,会显示tableView。

为了保存数据,我想在人们加入房间时将每个个人资料图片存储在文档目录中。现在这样做了,但是即使我两次调用它,tableView也会重新加载。因为它重新加载很多,所以它会因为数组超出索引而崩溃。

崩溃发生在图片阵列上,而不是用户名数组。这是我的代码(有点多):

private var playersRefHandle: FIRDatabaseHandle?
var channelRef: FIRDatabaseReference?

var players = [String]()
var playerImages = [UIImage]()
var playerUIDs = [String]()
var playersImageVersion = [String]()
var channel: Channel? {
    didSet {
        title = channel?.name
    }
}
override func viewDidLoad() {
    super.viewDidLoad()

    playersView.delegate = self
    playersView.dataSource = self
    let storage = FIRStorage.storage()
    let storageRef = storage.reference(forURL: "gs://X-f5beb.appspot.com")
    channelRef?.observeSingleEvent(of: .value, with: { (snapshot) in
        if let snapDict = snapshot.value as? [String:AnyObject]{
            for each in snapDict{
                let UIDs = each.value["userID"] as? String
                let pictureVersion = each.value["PictureVersion"] as? String
                if let allUIDS = UIDs{
                    if let allPictureVersions = pictureVersion{
                    self.playerUIDs.append(UIDs!)
                    self.playersImageVersion.append(allPictureVersions)
                        let userNames = each.value["username"] as? String
                        if let users = userNames{
                            self.players.append(users)
                        }
                    if self.checkDataExist(dataToCheck: "\(UIDs!)" + "Image.png") == false || self.isCurrentImageVersionStored(pathToImage: "\(UIDs!)" + "ImageVersion.txt", playersVersionImage: "\(allPictureVersions)") == false
                    {
                        print("image needs to be downloaded online")
                    let profilePicRef = storageRef.child((allUIDS)+"/profile_picture.png")
                    profilePicRef.data(withMaxSize: 1 * 500 * 500) { data, error in
                        if let error = error {
                        }
                        if (data != nil)
                        {
                            let image = UIImage(data: data!)
                            let convertImage = UIImagePNGRepresentation(image!)
                            let pathUIDImage = self.getDocumentsDirectory().appendingPathComponent(allUIDS + "Image.png")
                            try? convertImage!.write(to: pathUIDImage)
                            let playersUIDImageVersion = allPictureVersions
                            var pathUIDImageVersion = self.getDocumentsDirectory().appendingPathComponent(allUIDS + "ImageVersion.txt")
                            try? playersUIDImageVersion.write(to: pathUIDImageVersion, atomically: true, encoding: .utf8)
                            self.playerImages.append(UIImage (data: data!)!)


                        }
                        }
                        }
                        else
                    {

                        self.playerImages.append(self.retrieveImageFromDocuments(playersUID: UIDs!))

                        }

                }

                }

            }

        }
        self.playersView.reloadData()
        self.observePlayers()
    })

}
deinit {
    if let refHandle = playersRefHandle {
        channelRef?.removeObserver(withHandle: refHandle)
    }
}

override func willMove(toParentViewController parent: UIViewController?)
{
    if parent == nil
    {
        print("back")
    }
}

func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let documentsDirectory = paths[0]
    return documentsDirectory
}

func checkDataExist(dataToCheck: String) -> Bool
{
    let documentsURL = try! FileManager().url(for: .documentDirectory,
                                              in: .userDomainMask,
                                              appropriateFor: nil,
                                              create: true)
    let file = documentsURL.appendingPathComponent(dataToCheck)
    let fileExists = FileManager().fileExists(atPath: file.path)
    if fileExists == true
    {
        return true
    }
    else
    {
        return false
    }
}

func isCurrentImageVersionStored(pathToImage: String, playersVersionImage: String) -> Bool
{
    if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {

        let path = dir.appendingPathComponent(pathToImage)

        do {
            let currentStoredImage = try String(contentsOf: path, encoding: String.Encoding.utf8)
            let currentStoredImageInt = Int(currentStoredImage)
            let playersVersionImageInt = Int(playersVersionImage)
            if currentStoredImageInt == playersVersionImageInt
            {
                return true
            }
            else
            {
                return false
            }
        }
        catch {/* error handling here */}
        return false
    }
    return false
}

func retrieveImageFromDocuments(playersUID: String) -> UIImage
{
    print("image is available offline")
    let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
    let nsUserDomainMask    = FileManager.SearchPathDomainMask.userDomainMask
    let paths               = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
    let dirPath          = paths.first
       let imageURL = URL(fileURLWithPath: dirPath!).appendingPathComponent("\(playersUID)" + "Image.png")
        let profileImageForUser    = UIImage(contentsOfFile: imageURL.path)
        return profileImageForUser!
}

func observePlayers()
{
    playersRefHandle = channelRef?.child("username").observe(.childChanged, with: { (snapshot) -> Void in
        print("added player")
    })
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()

}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return players.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    print("configuring one of multiple cells")
    print(playerImages.count)
    print(players.count)
    var cell = tableView.dequeueReusableCell(withIdentifier: "playersCell") as! PlayersCellInMultiplayer
    cell.playersUsername?.text = players[indexPath.row] as String
    cell.playersImage?.image = playerImages[indexPath.row] as UIImage
    return cell
}

这是我打印的随机频道,其中包含少数用户:

image is available offline
image needs to be downloaded online
configuring one of multiple cells
1
2
configuring one of multiple cells
1
2

为什么会这样?这是异步方法吗?解决问题的最佳方法是什么?

0 个答案:

没有答案