从 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】:
您确实应该对 cmets 使用关系而不是数组,然后您有一个可以异步运行的查询来获取 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 上的用户指针中检索数据
使用 getdatainbackground 从 Parse 检索多个图像(IOS - Swift)