Swift:UIImages在表格视图中出现乱序

时间:2015-06-10 19:54:26

标签: ios swift uitableview uiimage

我正在查询来自Parse后端的图像,并在UITableView中按顺序显示它们。虽然我一次下载并显示一个,但在我的表视图中它们完全出现故障。每张图片(专辑封面)对应一首歌曲,因此每部歌曲的专辑封面都不正确。有人会如此善意地指出为什么他们出现故障?

 class ProfileCell: UITableViewCell {

        @IBOutlet weak var historyAlbum: UIImageView!

    }

    class ProfileViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!

    var historyAlbums = [PFFile]()
    var albumCovers = [UIImage]() 

   // An observer that reloads the tableView
    var imageSet:Bool = false {
            didSet {
                if imageSet {

                    // Reload tableView on main thread
                    dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) { // 1
                        dispatch_async(dispatch_get_main_queue()) { // 2
                            self.tableView.reloadData() // 3
                        }
                    }
                }
            }
        }

        // An observer for when each image has been downloaded and appended to the albumCovers array. This then calls the imageSet observer to reload tableView.
        var dataLoaded:Bool = false {
            didSet {
                if dataLoaded {

                    let albumArt = historyAlbums.last!
                    albumArt.getDataInBackgroundWithBlock({ (imageData, error) -> Void in

                        if error == nil {
                            if let imageData = imageData {
                                let image = UIImage(data: imageData)
                                self.albumCovers.append(image!)
                            }

                        } else {

                            println(error)

                        }
                        self.imageSet = true
                    })
                }
                self.imageSet = false
            }
        }

override func viewDidLoad() {
        super.viewDidLoad()

// Queries Parse for each image
var query = PFQuery(className: "Songs")
        query.whereKey("user", equalTo: PFUser.currentUser()!.email!)
        query.orderByDescending("listenTime")
        query.limit = 20
        query.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
            if error == nil {

                if let objects = objects as? [PFObject] {
                    for object in objects {
if let albumCover = object["albumCover"] as? PFFile {

                            // Appending each image to albumCover array to convert from PFFile to UIImage
                            self.historyAlbums.append(albumCover)

                        }

                        self.dataLoaded = true

                    }

                }

            } else {

                println(error)

            }

            self.dataLoaded = false

        })
    }

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var profileCell = tableView.dequeueReusableCellWithIdentifier("ProfileCell", forIndexPath: indexPath) as! ProfileCell

    profileCell.historyAlbum.image = albumCovers[indexPath.row]

        return profileCell

    }

 }

}

1 个答案:

答案 0 :(得分:1)

你让它们失灵的原因是你要为每个人单独解决后台任务。

您可以在后台线程中同时获取所有对象列表。那很好。然后,一旦你有了,你调用一个方法(通过didset)迭代该列表,并分别在他们自己的后台线程中获取每个。完成每个单独的线程后,将其结果添加到表数组中。您无法控制这些后台线程的完成时间。

我相信parse有一个同步的get方法。我目前还不确定语法。另一种选择是看你是否可以包括"具有初始请求的图像文件字节,这将使整个调用成为单个后台调用。

另一个选项(可能是最好的选项)是使用另一个数据(字典等)来标记每个图像文件请求的位置。然后,当完成单个背景获取后,您将知道该图像应该在最终数组中的位置。将下载的图像放在数组中您创建的字典所指示的位置。

这应该可以解决您的异步问题。