【问题标题】:getdatainbackgroundwithblock is returning nilgetdatainbackgroundwithblock 返回 nil
【发布时间】:2016-06-16 03:05:03
【问题描述】:

我尝试过使用其他解决方案,但没有成功。我需要将数据保存到 UIImages 数组中,因此在创建单元格时,它只需从已制作的图像数组中分配图像。问题是它返回零。我还需要确保图像是有序的。

/--UPDATING YOUR POSTS AFTER YOU POSTED--\\
func updatePosts(){
    if Reachability.isConnectedToNetwork() {
        self.images.removeAll(keepCapacity: true)

        let query = PFQuery(className: "Shoes")
        query.whereKey("createdBy", equalTo: PFUser.currentUser()!.username!)
        query.orderByDescending("createdAt")
        query.limit = 1000

        query.findObjectsInBackgroundWithBlock {
            (objects: [AnyObject]?, error: NSError?) -> Void in
            if error == nil {
                print("Successfully retrieved \(objects!.count) scores.")
                for object in objects! {

                    let imageFile = (object["imageFile"] as! PFFile)
                    imageFile.getDataInBackgroundWithBlock{
                        (imageData: NSData?, error: NSError?) -> Void in
                        if error == nil {
                            let image = UIImage(data: imageData!)
                            self.images.append(image!)
                        }
                    }

                    self.ids.append(object.objectId as String!)
                }
                dispatch_async(dispatch_get_main_queue(), {
                    self.collectionView.reloadData()
                })
            }
            else {
                print(error)
            }
        }


    } else {
        print("Internet connection not available")
        // This is Depreciated!!
        let alert = UIAlertView(title: "No Internet connection", message: "Please ensure you are connected to the Internet", delegate: nil, cancelButtonTitle: "OK")
        alert.show()
    }
}

【问题讨论】:

    标签: ios arrays swift parse-platform


    【解决方案1】:

    您实际上有一个相当复杂的问题。你有一个外部异步调用query.findObjectsInBackgroundWithBlock,它将一个对象数组传递给它的完成闭包,这很好。

    在该闭包中,您运行一个循环,创建一大堆异步调用来加载图像。这些调用不会在不可预知的时间内完成。

    通常我会说使用调度队列和调度组,这样您就可以等到所有任务完成,但我假设您没有重写imageFile.getDataInBackgroundWithBlock() 函数的选项。

    我要做的是添加一个实例变量taskCount,它跟踪要完成的任务数量,在主线程上运行一个闭包以在每次异步下载完成时递减taskCount,并告诉完成所有任务后重新加载的表视图:

    //Put this outside the function and inside the definition of your class so it's
    //an instance variable
    var taskCount: Int 
    

    然后将您的调用改写为query.findObjectsInBackgroundWithBlock,如下所示:

    query.findObjectsInBackgroundWithBlock 
    {
      (objects: [AnyObject]?, error: NSError?) -> Void in
      if error == nil 
      {
        print("Successfully retrieved \(objects!.count) scores.")
        //Remember how many getDataInBackgroundWithBlock calls have to run 
        //before we're done
        taskCount = objects.count
        //create an array of optionals and fill it with nils
        var tempImageArray = [UIImage?](count: objects.count, repeatedValue: nil)
        for (index, object) in objects!.enumerate() 
        {
          let imageFile = (object["imageFile"] as! PFFile)
          imageFile.getDataInBackgroundWithBlock
          {
            (imageData: NSData?, error: NSError?) -> Void in
            if error == nil 
            {
              let image = UIImage(data: imageData!)
              tempImageArray[index = image;
    
              //We're done with this one, so tell the main thread
              //to decrement the taskCount
              dispatch_async(dispatch_get_main_queue()) 
              {
                taskCount--
                if taskCount == 0
                {
                  self.images = tempImages.map({$0!})
                  self.collectionView.reloadData()
                }
              }
            }
          }
      }
    }
    

    该代码同时运行您对imageFile.getDataInBackgroundWithBlock 的所有调用,但调用主线程以减少每个完成闭包中的taskCount。通过减少主线程上的taskCount,您可以避免竞争条件,并且仅在下载所有图像并且完全填充self.images 数组后才告诉表视图重新加载。

    应该可以。 (我是在 SO 文本编辑器中编写的,因此可能需要进行少量清理。大括号看起来没有正确平衡,但它应该可以让您了解。)

    编辑:

    我更改了上面的代码以保留列表中结果对象的顺序,然后再次对其进行编辑以修复 for 循环以使用 enumerate() 函数。 (我忘记了。)

    【讨论】:

    • 这实际上并没有按顺序获取图片。除此以外,一切正常。此外,当图像加载时,它们不是 uicollectionviewcell 的完整大小
    • 对。您开始的代码是专门为一次下载所有图像而编写的,它们将以半随机顺序完成。您需要按特定顺序下载它们,还是仅按特定顺序保存到您的阵列中?
    • 我需要它们以一定的顺序显示。所以我只需要它们以特定的方式存储。我正在尝试将它们加载到我的集合视图中,并首先出现最新创建的。我不在乎先下载哪个,只要它们正确存储在数组中即可。
    • @ConnorB,我编辑了我的代码,以与imageFile 对象数组相同的顺序构建图像数组。它首先创建一个由 nil 填充的临时选项数组,然后将每个完成的图像放入临时数组中正确的索引处。
    • 然而,上面的代码不处理对象 ID。您需要对我上面用于图像数组的对象 ID 使用相同的方法。我会留给你去弄清楚。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 2019-06-20
    • 2017-12-16
    • 2014-09-27
    • 2017-06-11
    • 2014-12-29
    • 2019-03-14
    相关资源
    最近更新 更多