从 Parse 中的指针数组中检索对象的更有效方法,然后在 Swift 中更新 uitableview

Posted

技术标签:

【中文标题】从 Parse 中的指针数组中检索对象的更有效方法,然后在 Swift 中更新 uitableview【英文标题】:More efficient way of retrieving objects from array of pointers in Parse, then updating uitableview in Swift 【发布时间】:2015-09-24 16:20:31 【问题描述】:

我已经将一个 Parse“事件”对象传递给 viewController。无需查询。

此“事件”对象包含指向解析“注释”对象的指针数组。

我对“评论”对象的两个属性感兴趣。两者都是名为“commentAuthor”和“commentText”的字符串。

我有一个具有原型单元格的 UITableView,它需要显示“commentAuthor”和“commentText”字符串。

它目前正在运行,但我对我的工作方式不满意,就是这样:

var commentsArrayOfPointers: [AnyObject]?
var commentsArrayOfObjects = [PFObject]()

func dealWithCommentPointers() 

    //get array of pointers from "Event" object
    commentsArrayOfPointers = theEvent!["commentsArray"] as? [AnyObject]

    commentsArrayOfObjects.removeAll()

    //loop through each pointer, and "Fetch" its associated "Comment" object,
    //then append that "Comment" object to my array of "Comment" objects
    for comment in commentsArrayOfPointers! 

        comment.fetchIfNeeded()

        commentsArrayOfObjects.append(comment as! PFObject)

    

    //print(commentsArrayOfObjects)

    self.tableView.reloadData()


然后,我像这样构建表格单元格,从之前填充的“cmetsArrayOfObjects”中提取数据:

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

    let cell = tableView.dequeueReusableCellWithIdentifier("commentCell",
      forIndexPath: indexPath) as! commentCellClass

    cell.commentCellNameLabel.text = commentsArrayOfObjects[indexPath.row]["commentAuthor"] as! String
    cell.commentCellCommentLabel.text = commentsArrayOfObjects[indexPath.row]["commentText"] as! String

    return cell

它有效,但我对在每个评论对象上使用 Parse 命令“fetchIfNeeded()”并不感到兴奋,因为它是一个同步函数,这意味着它会导致我的应用程序在显示表格之前暂停。我更喜欢使用异步函数,它允许加载视图控制器的其余部分,然后 cmets 将在表可用时填充表。

我尝试做一个异步命令fetchInBackgroundIfNeeded(),但当然它在原型单元构建之前没有完成,导致崩溃(因为它正在寻找数据的数组为零)。

我还尝试在我需要的“事件”上设置一个 PFQuery(虽然我已经有了该事件,但不需要重新查询它)并在“事件”的“cmetsArray”属性上添加一个“includeKey” “ 班级。然后在查询结束时,我做了一个self.tableView.reloadData(),但这也不起作用。这里似乎有一个更大的问题,因为查询似乎从未执行过,并且表重新加载,即使我已经注释掉了这样做的代码。这是那个尝试(我认为更接近我的问题的正确解决方案):

func dealWithCommentPointers() 

    print("inside the function")

    var query = PFQuery(className: "Event")
    let objectIdToLookup = self.theEvent?.objectId
    query.whereKey("objectId", equalTo: objectIdToLookup!)
    query.includeKey("commentsArray")

    query.findObjectsInBackgroundWithBlock  (results, error) -> Void in

        if error != nil 
            print("Error found")
            print(error)
        


        else 

            let eventArray = results as! [PFObject]

            let theEventToDisplayCommentsFor = eventArray[0] //this should always be [0]

            print("yo dude")

            self.commentsArrayOfObjects = theEventToDisplayCommentsFor["commentArray"] as! [PFObject]

            print("hey here i am!")

            print(self.commentsArrayOfObjects.count)

            self.tableView.reloadData() //even tried commenting this out, it is still called?!

        

    


那么,有什么想法吗?

【问题讨论】:

【参考方案1】:

为什么不预先在数组中包含所有Comment 对象?我的猜测是您已经在前一个视图控制器上执行了一个查询,这就是您要传递 Event 对象的方式。当您执行该查询时,请在数组上使用 includeKey,以便所有 Comment对象与查询同时返回。

如果无法做到这一点,我建议您在表格视图中添加几个函数,以便从 Parse 中异步获取数据,然后重新加载表格。 Here's an example for doing that which I've posted before。在那个例子中,有一个 UISearchController 但想法是一样的。

【讨论】:

谢谢拉塞尔。我考虑过事先传入Comment 对象。这似乎是最简单的解决方案,但我获得当前 viewController 的方法之一是“创建事件”视图控制器,然后我在其中设置“事件”对象以传递给当前 viewController 的 prepareForSegue 方法先前(或“创建事件”)viewController。当来自这个 VC 时,总是会有零个“评论”对象,但似乎我必须进行查询才能将 commentsArray 包含在其中。我想它不会杀死我做另一个查询,但似乎很浪费? 那么,我想到了你所说的在我的表格视图中添加几个函数。我想这样做,但我不知道怎么做。我仔细查看了您的链接问题,但我真的不明白它如何适用于我正在做的事情。我在您的 tableView 代码中看到了一些 if 语句,但没有附加功能。我可能错过了什么...... 我不明白如果事件刚刚创建,您为什么需要添加另一个查询。在那种情况下,不会只有 0 cmets 并且表格视图会是空的吗?我链接的示例是提供使用PFQueryTableViewController 的替代方法。通过使用您自己的表格视图控制器并实现您自己的访问 Parse 的功能,您将拥有更多的灵活性。 if 语句仅适用于搜索控制器,您可以忽略这些情况。您只需要数组容器和 Parse 方法。 谢谢拉塞尔。我没有使用PFQueryTableViewController。我确实在使用我自己的 tableViewController。我在前一个视图控制器中创建事件,并将 cmets 数组存储在该事件中。但是,Parse 将它们存储为“指针”。所以,我不确定如何将实际对象传递给下一个视图控制器,使用事件对象,而不使用 includeKey 进行 Parse 查询。对于您的问题,是的,当您创建事件时,cmets 将为零,并且 tableView 将为空。但我想我必须传入这个对象数组,即使它是空的...... 乐于助人。由于您传入了Event,我猜您在表视图中定义了一个PFObject,它在前一个视图控制器上的prepareForSegue 期间设置。类似地,您可以在表视图中为在 prepareForSegue 期间设置的 cmets 定义一个 [PFObject] 数组。【参考方案2】:

您确实应该对 cme​​ts 使用关系而不是数组,然后您有一个可以异步运行的查询来获取 cmets。此外,您需要更改表格视图设置,以便在您还没有任何 cmets 时它不会崩溃。您没有说明它为什么崩溃,所以我无能为力,但是您应该在查询正在进行时确实有一个活动指示器,然后用真实的单元格或一个指示还没有 cmets 的单元格替换它。

从技术上讲,使用异步获取对于少量 cmets 应该同样有效,但是当您添加更多 cmets 时,您会发出更多网络请求,并且很快您将淹没网络并且它们都会失败。

【讨论】:

谢谢韦恩。如果我不能让我目前的工作方式,我会放弃并重新考虑使用关系。我预计每场比赛最多的参赛人数不超过 20-30 cmets。如果那样的话,可能更像是5-10。您对我将异步获取代码放在哪里有什么建议吗?我尝试在返回我的自定义 cell 的函数中执行此操作,但我无法在该 Parse 函数 (findObjectsInBackgroundWithBlock) 中返回任何内容,或者我可以,我只是不知道? 我有代码可以防止 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 运行,除非它有要查看的数据,但感谢您的注意。 您应该在加载视图时加载 cmets,而不是在尝试配置单元格时加载,然后重新加载表格 谢谢韦恩。我已经在这样做了。我有一个在viewWillAppear 中调用的函数(dealWithCommentPointers)。在该函数结束时,我在 tableView 上调用 reloadData 那么为什么会发生崩溃?如果表等待数据,那么一切都很好

以上是关于从 Parse 中的指针数组中检索对象的更有效方法,然后在 Swift 中更新 uitableview的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 swift 从 Parse 上的用户指针中检索数据

检索 Firebase 数据的更有效方法?

使用 getdatainbackground 从 Parse 检索多个图像(IOS - Swift)

使用犰狳做 `Q.slice(a).col(b)` 的更有效方法

非指针 复制对象和数组的两种方法

从Parse.com删除特定对象