在循环结束后,在 for 循环运行中查找对象在背景中与块,所以我无法访问基于迭代计数器的数组元素



我使用的是parse.com和Swift 2。

我需要在for循环中从parse中查找对象。问题是,findObjectsInBackgroundWithBlock是异步的,所以当query.findObjectsInBackgroundWithBlock中的闭包运行时,循环已经完成,迭代(i)的索引比opIdList.count大。所以我得到了数组索引超出范围的错误,因为opIdList、opUserIdlist和opLastIdChangedToList具有相同数量的元素。有没有我缺少的简单解决方案,或者我必须使用同步功能?(在本例中为findObjects())

        for var i = 0; i < opIdList.count; ++i {
            let query = PFQuery(className: "LastId")
            query.whereKey("UserId", equalTo: opUserIdList[i])
            query.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
                if error == nil {
                    if objects?.count != 0 {
                        for object in objects! {
                            object.setValue(self.opLastIdChangedToList[i], forKey: "lastId")
                            object.saveInBackground()
                            processedOnes.append(i)
                        }
                    } else {
                        let item = PFObject(className: "LastId")
                        item["lastId"] = self.opLastIdChangedToList[i]
                        item["userId"] = self.opUserIdList[i]
                        item.saveInBackground()
                        processedOnes.append(i)
                    }
                }
            })

您可以使用递归而不是for循环。我不太理解你的代码中发生了什么,但我在下面的递归中实现了for循环的作用。

func reccursiveRquest(index:Int) {
    let query = PFQuery(className: "LastId")
    query.whereKey("UserId", equalTo: opUserIdList[index])
    query.findObjectsInBackgroundWithBlock({ (objects, error) -> Void in
        if error != nil {
            if objects?.count != 0 {
                for object in objects! {
                    object.setValue(self.opLastIdChangedToList[index], forKey: "lastId")
                    object.saveInBackground()
                    processedOnes.append(index)
                }
                if (index++) < opIdList.count { reccursiveRquest(index) }
            } else {
                let item = PFObject(className: "LastId")
                item["lastId"] = self.opLastIdChangedToList[index]
                item["userId"] = self.opUserIdList[index]
                item.saveInBackground()
                processedOnes.append(index)
                if (index++) < opIdList.count { reccursiveRquest(index) }
            }
        }
    })
}

正如您所说,正如名称findObjectsInBackgroundWithBlock所暗示的,它在后台运行,因此是异步的。你不能用这种方式做你想做的事。

要么需要更改逻辑以允许异步任务完成,然后完成处理,要么需要同步运行查询(并确保不会不适当地阻塞当前线程,尤其是当该线程是主线程时)。

可以通过用NSNull填充数组,然后在到达时替换每个项来完成前者。您将需要一些方法来检查是否所有操作都已完成,以便触发数组是否已准备好使用。

在某些方面,最好使其同步并在后台线程上运行整个过程,因为这也可以防止您同时向网络发出过多请求。然后,知道什么时候完成并且可以返回整个完成的数组也是很琐碎的。

最新更新