数组索引超出范围 - 从Parse下载图像

时间:2016-02-29 21:33:38

标签: ios swift parse-platform tableview

我正在尝试从解析中查询图像,当我打开我的应用程序时,一切正常,但如果我尝试刷新,我会在下面显示此崩溃...

enter image description here

不太确定导致这种情况的原因......要解释一下我是如何设置的:

我有一个带有1个单元格的tableView,在该单元格中有三个连接到集合Outlet的imageView。然后我从解析中获取我的图像并将它们放在我的imageViews中,然后在numberOfRowsInSection中将它除以3,这样它就不会重复图像3次......!

以下是我的代码:

    var countries = [PFObject]()



    override func viewDidLoad() {
        super.viewDidLoad()

       loadPosts()


        // Do any additional setup after loading the view.
    }

 func loadPosts() {
        PFUser.query()
        // Build a parse query object
        let query = PFQuery(className:"Post")
        query.whereKey("user", equalTo: PFUser.currentUser()!)
        query.orderByDescending("createdAt")


        // Fetch data from the parse platform
        query.findObjectsInBackgroundWithBlock {
            (objects: [PFObject]?, error: NSError?) -> Void in

            // The find succeeded now rocess the found objects into the countries array
            if error == nil {

                self.countries.removeAll(keepCapacity: true)

                if let objects = objects {
                    self.countries = Array(objects.generate())
                }

                // reload our data into the collection view
               self.tableView.reloadData()

            } else {
                // Log details of the failure
                print("Error: \(error!) \(error!.userInfo)")
            }
        }


    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {

       return countries.count / 3

    }

    var counter = 0
     override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
     {

      let cell = tableView.dequeueReusableCellWithIdentifier("cell2") as! bdbTableViewCell


        for imageView in cell.threeImages {
            let placeHolder = UIImage(named: "camera")
             imageView.image = placeHolder

            let finalImage = countries[counter++]["imageFile"]
            finalImage!.getDataInBackgroundWithBlock {
                (imageData: NSData?, error: NSError?) -> Void in
                if error == nil {
                    if let imageData = imageData {
                        imageView.image = UIImage(data:imageData)
                    }
                }
            }}
            return cell
    }

3 个答案:

答案 0 :(得分:-1)

var counter = 0 

应在功能

之前重置
cellForRowAtIndexPath

答案 1 :(得分:-1)

问题

您将counter变量声明为静态。这就是为什么它不会在cellForRowAtIndexPath次调用之间重置,但每次调用该方法时它都会增加。

解决方案:

counter声明移至函数体。如下所示:

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

    var counter = 0

    let cell = tableView.dequeueReusableCellWithIdentifier("cell2") as! bdbTableViewCell

        for imageView in cell.threeImages {
            let placeHolder = UIImage(named: "camera")
             imageView.image = placeHolder

            let finalImage = countries[counter++]["imageFile"]
            finalImage!.getDataInBackgroundWithBlock {
                (imageData: NSData?, error: NSError?) -> Void in
                if error == nil {
                    if let imageData = imageData {
                        imageView.image = UIImage(data:imageData)
                    }
                }
            }}
            return cell
    }

答案 2 :(得分:-1)

如果我了解您的数据,则需要移动到包含您所在国家/地区第一张图像的数组中的位置,然后迭代接下来的3张图像。

基本上,您应该在函数体内移动计数器声明,并使用第一个图像的位置对其进行初始化。有关完整实现,请参阅下面的方法定义。

你的代码第一次通过剪切运气工作。基本上iOS将在第1行请求单元格,并且您的计数器将通过在索引0,1和2处获取图像来增加自身。然后iOS将在第2行请求单元格,它将拉出图像3,4,5。计数器将继续递增。然后,当您刷新表时,计数器仍然设置为高于图像数组大小的数字,因此您会崩溃。如果iOS因任何原因要求不同顺序的单元格,您也会错误地显示图像。您需要使用indexPath.row参数来获取正确的图像。

在3的倍数结束后,您的代码也不会考虑其他图像。因此,如果有17张图像,则图像16 1和17将不会在tableview中显示一行。要更正此问题,请添加以下函数:

func roundUp(value: Double) -> Int {
    if value == Double(Int(value)) {
        return Int(value)
    } else if value < 0 {
        return Int(value)
    } else {
        return Int(value) + 1
    }
}

然后将tableView的numberOfRowsInSection方法更改为以下内容:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
    return roundUp(Double(countries.count / 3.0))
}

最后,在您的cellForRowAtIndexPath函数中,您必须处理可能尝试查找超出数组大小的图像:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    var imageIndex = (indexPath.row * 3)

    let cell = tableView.dequeueReusableCellWithIdentifier("cell2") as! bdbTableViewCell

    for imageView in cell.threeImages {
        let placeHolder = UIImage(named: "camera")
        imageView.image = placeHolder

        if imageIndex < countries.count
        {
            let finalImage = countries[imageIndex++]["imageFile"]
            finalImage!.getDataInBackgroundWithBlock {
                (imageData: NSData?, error: NSError?) -> Void in
                if error == nil {
                    if let imageData = imageData {
                        imageView.image = UIImage(data:imageData)
                    }
                }
            }
        }
    return cell
}

我相信这会解决你所有的问题。我建议您学习UITableView如何工作的教程,以及如何单步执行自己的代码进行故障排除。这样你就可以理解为什么原来的尝试不起作用了。