iOS Parse SDK:将多个查询结果放入一个数组

Posted

技术标签:

【中文标题】iOS Parse SDK:将多个查询结果放入一个数组【英文标题】:iOS Parse SDK: Multiple query results put into an Array 【发布时间】:2014-06-12 20:06:23 【问题描述】:

场景 = 我有一个应用程序,用户可以在其中相互发送消息、评论和被查询以填充当前用户的通知表视图的戳。必须进行 3 个查询,一个用于消息,两个用于评论,三个用于 Pokes。我正在使用的代码如下...

PFQuery *messageQuery = [PFQuery queryWithClassName:@"Message"];
[messageQuery whereKey:@"receiverID" equalTo:[PFUser currentUser][@"userID"]];
[messageQuery orderByDescending:@"createdAt"];
[messageQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) 

    messages = objects;    

];

PFQuery *pokeQuery = [PFQuery queryWithClassName:@"Poke"];
[pokeQuery whereKey:@"receiverID" equalTo:[PFUser currentUser][@"userID"]];
[pokeQuery orderByDescending:@"createdAt"];
[pokeQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) 

    pokes = objects;    

];

PFQuery *commentsQuery = [PFQuery queryWithClassName:@"Comment"];
[commentsQuery whereKey:@"receiverID" equalTo:[PFUser currentUser][@"userID"]];
[commentsQuery orderByDescending:@"createdAt"];
[commentsQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) 

    comments = objects;    

];

需要什么 = 将以下数组:“messages”、“pokes”和“cmets”合并到一个数组 (notificationsArray) 中,我可以按“createdAt”对其进行排序,并使用 notificationsArray objectAtIndexPath:indexPath 填充我的 notificationsTableView。排。

我遇到的问题=(有两个)

(1) 当我 NSLog 任何这些查询的结果时...

PFQuery *messageQuery = [PFQuery queryWithClassName:@"Message"];
[messageQuery whereKey:@"receiverID" equalTo:[PFUser currentUser][@"userID"]];
[messageQuery orderByDescending:@"createdAt"];
[messageQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) 

    messages = objects;    

];

NSLog(@"messages = %@", messages);

它记录“messages = (null)”。我无法为我的生活弄清楚为什么它没有被设置。我知道有消息,因为当我 NSLog 来自查询的“对象”数组时,它给了我想要的东西。这就像查询的内容不会离开查询本身的范围。上面的所有查询都是这样做的。如果我无法从该块中获取查询的内容,那么我无法创建所有数组的数组来填充notificationsTableView,所以我搞砸了。请帮忙。

(2) 即使我确实将查询的结果放入单个数组中,我也不确定如何创建数组数组并通过键对其进行排序。谁能帮我这个?请。

【问题讨论】:

【参考方案1】:

你可能正在寻找+orQueryWithSubqueries:(NSArray *)queries方法,但是我不明白返回值描述是什么:

a PFQuery that is the or of the passed in PFQueries

我认为这意味着||(或)?

你会这样做:

NSArray *queryArray = [NSArray arrayWithObjects:messageQuery,pokeQuery,commentsQuery,nil];
PFQuery *allQueries = [PFQuery orQueryWithSubqueries:queryArray];
[allQueries findObjects... 

至于第二个错误,你是对的,没有保留值,因为当块失去作用域时,内部的所有局部变量都会在自动释放池中被销毁。您需要通过使用强大的属性来保留它。 self.messages = objects;

【讨论】:

【参考方案2】:

(1) 您在回调函数之外记录消息,并且日志出现在回调函数返回之前。尝试在分配后将消息记录到您的回调中。

[messageQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) 
    messages = objects;    
    NSLog(@"messages = %@", messages)
];

(2) 在排序之前,创建一个 NSMutableArray 并对每个检索到的数组使用addObjectsFromArray: 方法。

要对通知进行排序,您应该使用 NSSortDescriptor,它是一种描述如何根据所包含对象的格式对数组进行排序的机制。这是一个可以满足您需求的示例:

NSSortDescriptor *createdAtDescriptor = [[NSSortDescriptor alloc] initWithKey:@"createdAt" ascending:YES];
notificationsArray = [messages sortedArrayUsingDescriptors:@[createdAtDescriptor]];

希望对您有所帮助!

编辑:您可以将临时 NSMutableArray 嵌入到自动释放池中以避免无用的内存泄漏,以便在您继续显示后立即释放专用内存。

编辑:您可以使用orQueryWithSubqueries Parse 方法将多个请求合并为一个请求。在你的情况下这并不烦人,因为你正在根据它们的 createdAt 键对 PFObject 进行排序,这对每个 PFObject 来说都是通用的。在任何情况下,您都必须检查 PFObject 类型以根据它们的类型显示它们。请参阅full documentation here。 不适用于返回多种对象的查询!

【讨论】:

我意识到,如果我在将消息数组分配给 = 对象之后立即使用 NSLog,它将显示在我的调试中。这从来都不是问题。我将其从回调中 NSLogged 的​​原因是为了说明消息数组未设置在回调之外 - that 是问题所在。为了创建所有回调的数组,我需要能够做到这一点,以便我可以按照您描述的方式对它们进行排序(顺便说一句,非常感谢您),以便我可以用数组填充我的 tableView。 我猜你错过了什么。您必须在回调中分配数组,然后在分配数组后立即使用 reloadData 选择器强制重新加载表视图,仍在回调中。您的分配在回调之外应用,但只有一次回调被调用。 我试过 orQueryWithSubqueries。它出错了... *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“或查询的所有子查询都应该在同一个类上” 在您的情况下似乎无法使用此方法,请保留您之前发布的版本。如果我的回答对你有帮助,请投票! 阅读我原始答案的第二部分,并使用最终数组上的属性保留引用。您可以考虑了解 Objective-c 和 Cocoa 开发的基础知识。

以上是关于iOS Parse SDK:将多个查询结果放入一个数组的主要内容,如果未能解决你的问题,请参考以下文章

解析 iOS SDK:无法从数组中获取对象

Apple要求使用Parse-iOS-SDK对info.plist进行“NSLocationAlwaysUsageDescription”描述

将 tvOS Parse SDK 添加到现有 iOS 项目

Parse 的 iOS SDK(或其他 SDK)如何解决冲突?

doesNotMatchKey:inQuery: 在 Parse SDK for iOS 中返回匹配键的记录

如何在 AppDelegate 中使用 Parse 正确设置 Facebook iOS SDK?