数组返回PFQuery之外的空数组与解析

问题描述:

我想填充数组postCaptions。 我需要将此数组返回给我的表视图的numberOfRowsInSection,但它每次都返回一个空数组。数组返回PFQuery之外的空数组与解析

var postCaptions = [String]() 

    query2.whereKey("userid", equalTo: PFUser.current()?.objectId!)       
    query2.findObjectsInBackground(block: { (objects, error) in 
     if let userPosted = objects {  
      for object in userPosted {   
       if let userPost = object as? PFObject {   
        self.postImageFiles.append(userPost["userPostImage"] as! PFFile)          
        self.postLocation.append(userPost["userPostLocation"] as! String) 
        self.postCaptions.append(userPost["postCaption"] as! String) 
        print(self.postCaptions.count) //returns value of 2 for the two posts that I've made     
        self.tableView.reloadData()    
        self.refresher.endRefreshing() 
       } 
      } 
     } 

    })   
    print(self.postCaptions.count) //Returns empty array 

我知道问题出在线程的顺序,我明白,但我不知道我能做些什么使阵列保持查询之外填充。我已经将此视为解决此问题的一种方法,但我真的没有找到直接的解决方法,可以在代码中解决这个问题。如果有人能提供我的代码问题的解答,这将是惊人的!:)我一直坚持这个问题的一个多星期,现在

var postCaptions = [String]() { 
didSet { 
    // Do any execution that needs to wait for postCaptions here. 
} 
} 

** cellForRowAt

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "userPhotoFeedCell", for: indexPath) as! FeedCell 

    if PFUser.current()?.objectId != nil { 

     cell.userUsername.text = PFUser.current()?.username 

    } 


    //downloads images for user profile pic 
    imageFiles[indexPath.row].getDataInBackground { (data, error) in 

     if let imageData = data { 

      let downloadedImage = UIImage(data: imageData) 

      cell.userProfilePic.image = downloadedImage 

     } 


    } 

    //downloades images and items to populate user post 
    postImageFiles[indexPath.row].getDataInBackground { (data, error) in 

     if let userPostImageData = data { 

      let downloadedUserPostImage = UIImage(data: userPostImageData) 

      cell.userFeedPhoto.image = downloadedUserPostImage 

     } 


    } 

    cell.postLocation.text = postLocation[indexPath.row] 

    cell.postCaption.text = postCaptions[indexPath.row] 

    cell.userFeedPhoto.image = UIImage(named: "OrangeFuego") 

    cell.userProfilePic.image = UIImage(named: "usericon.png") 

    return cell 

} 
+0

'findObjectsInBackground'以异步方式工作。打印行在数据返回之前执行。将打印线放入完成块。 – vadian

+0

是的,但我需要延迟numberOfRowsInSection的调用,直到完成块完成加载,并因此给出了postCaptions的值 –

+0

'numberOfRowsInSection'从框架中调用。填充数据源数组并调用'reloadData()'。 – vadian

如果我理解你的问题很简单。将var postCaptions = [String]()设置为所需类别中的全局变量。然后将您的值从迭代中附加到您完成的方式。然后,可以在代码的其他部分访问postCaptions值,并且可以使用count属性。

+0

变量不是问题,问题在于findObjectsInBackground在调用numberOfRowsInSection之前永远不会完成,所以数组始终为0 –

由于方法findObjectsInBackground暗示它在后台执行,这意味着它与您的UI无关,因此在完成此功能之前,您的数组将保持为空。在打印该数组时,此功能尚未完成,因此postCaptions现在将为空。

而且这就是为什么numberOfRows将为零。

我认为您需要做的是将此查询放入viewDidLoad或您指定的初始化程序中,然后像在完成程序段中一样调用tableView.reloadData()。此外,您可能需要声明Bool,以确定表是否正在加载,并且在完成块中,成功执行查询后将isLoading设置为false。

query2.findObjectsInBackground(block: { (objects, error) in 

    if let userPosted = objects { 
     self.isLoading = false 

     for object in userPosted { 

      if let userPost = object as? PFObject { 

       self.postImageFiles.append(userPost["userPostImage"] as! PFFile) 

       self.postLocation.append(userPost["userPostLocation"] as! String) 

       self.postCaptions.append(userPost["postCaption"] as! String) 

       print(self.postCaptions.count) //returns value of 2 for the two posts that I've made 

      } 

     } 

     self.tableView.reloadData() 

     self.refresher.endRefreshing() 

    } 

}) 

和里面的numberOfRowsInSection

if isLoading { //you need to declare isLoading 
    return 1 //maybe a dummy cell to tell user the table is loading 
} else { 
    return postCaptions.count 
} 
+0

我喜欢这里要去的地方,但是我试过了,isLoading永远不会等于false,因为在调用NumberOfRowsInSection时,findObjectsInBackground始终会继续加载。我需要一些方法来等待findObjectsInBackground完成,然后再调用其余的方法。 –

+0

@FinnWolff也许你应该在你的'for-in'循环外加'reloadData()'和'self.isLoading = false'。看到我上面编辑的答案。由于在查询(后台线程)完成执行后你已经调用了'reloadData()',因此理论上,设置后'isLoading'应该是false。因为每次调用reloadData()时,都会调用'numberOfRows'方法。 –

+0

因此,我将print(“IT WORKED”)添加到了numberOfRowsInSection的if isLoading = false return postCaptions.count部分。它确实工作!该数组是填充和一切,但是当我滚动应用程序中的饲料崩溃,说:索引超出范围 –