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

Posted

技术标签:

【中文标题】解析 iOS SDK:无法从数组中获取对象【英文标题】:Parse iOS SDK: Not able to fetch Objects from Array 【发布时间】:2014-06-03 20:59:23 【问题描述】:

我有一个显示 Facebook 朋友数据的表格视图。数据存储在 Parse 上,我将其拉下并使用以下查询将数据存储在“postArray”中。我已经使用 NSLog 来检查 postArray 对象,我得到了想要的结果。

发生的情况是,我将存储在 postArray 中的数据的 sum 设置为适当的标签,然后一些就留空了。正如我所说,我做了 NSLog postArray,它给了我想要的东西。但是当我去设置数据时,它并没有设置所有数据,而是设置了一些数据。

问题 #1--> 我需要能够从数组中访问所有数据,但它不允许我这样做。

问题#2 --> 在运行时是否加载anything 是命中还是未命中。如果我登录并注销它是否会加载任何东西。我 NSLog postArray ,有时数组似乎是空的。我知道你在想什么——“你必须给我一些比“有时”更好的东西,但我真的做不到。它是命中注定的。

请帮帮我,告诉我这是怎么回事!

(并且 dispatch_async 没有区别)

我一直在做什么 =

    [[FBRequest requestForMyFriends] startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) 

        if (!error) 

            friendDict = result;

            friendArray = friendDict[@"data"];

            for (NSDictionary *friendObject in friendArray) 

                friendIDs = [NSMutableArray arrayWithObjects:[friendObject objectForKey:@"id"], nil];

                PFQuery *postQuery = [PFQuery queryWithClassName:@"Post"];
                [postQuery whereKey:@"postedByID" containedIn:friendIDs];
                [postQuery orderByAscending:@"createdAt"];
                [postQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) 

                    dispatch_async(dispatch_get_main_queue(), ^

                        postArray = objects;
                        [self.activityTableView reloadData];

                    );

                ];

            
        

        else 

            //there are errors

        

    ];

【问题讨论】:

看起来您正在为每个朋友进行查询...也许您想在查询之前关闭您的 for 循环.. 【参考方案1】:

我可以看到这段代码可能出错的几种方式。首先,看起来 postArray 每次内部查找完成时都会被替换。其次,内部查找的结构有问题,快速连续启动 N 个异步调用,然后在每个竞争时更新一个表。

考虑这个替代方案:我们构建了一些可以使用完成块运行异步的方法。对于基于userId 的帖子,最简单的是PFQuery

- (void)getPostsForId:(NSString *)userId withCompletion:(void (^)(NSArray *, NSError *))completion 

    PFQuery *postQuery = [PFQuery queryWithClassName:@"Post"];
    [postQuery whereKey:@"postedByID" containedIn:@[userId]];
    [postQuery orderByAscending:@"createdAt"];
    [postQuery findObjectsInBackgroundWithBlock:completion];

第二个是有趣的。这解决了进行一系列异步调用的问题,让一个在启动下一个之前完成,并且只有在所有都完成时才调用它的完成块。

它通过使用用户 ID 数组作为待办事项列表并递归调用自身,将结果收集到一个可变数组中来实现这一点。当待办事项列表完成(空)时,它会调用它自己的完成块:

- (void)getPostsForIds:(NSArray *)ids results:(NSMutableArray *)results completion:(void (^)(BOOL))completion 

    if (ids.count == 0) return completion(YES);

    NSString *userId = ids[0];
    NSArray *remainingIds = [ids subarrayWithRange:NSMakeRange(1, ids.count-1)];

    [self getPostsForId:userId withCompletion:^(NSArray *posts, NSError *error) 
        if (!error) 
            [results addObjectsFromArray:posts];
            [self getPostsForIds:remainingIds results:results completion:completion];
         else 
            completion(NO);
        
    ];

现在可以简化您开始使用的方法。从 FB 获取好友列表,构建他们的 id 数组,然后调用上面的魔法函数:

- (void)getFriendsPosts 

    [[FBRequest requestForMyFriends] startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) 
        if (!error) 
            friendDict = result;
            friendArray = friendDict[@"data"];

            NSMutableArray *ids = [NSMutableArray array];

            for (NSDictionary *friendObject in friendArray) 
                [ids addObject:[friendObject objectForKey:@"id"]];
            
            NSMutableArray *allPosts = [NSMutableArray array];
            [self getPostsForIds:ids results:allPosts completion:^(BOOL success) 

                // EDIT - be sure to use the resulting allPosts as your datasource
                self.theModelForMyTable = allPosts;

                [self.activityTableView reloadData];
                // if !success do an alert or something
            ];
        
    ];

数据源方法应该只引用表格模型,例如 numberOfRowsInSection 应该回答 self.theModelForMyTable.count 并且 cellForRowAtIndexPath 应该总是从 self.theModelForMyTable[indexPath.row] 获取配置单元格的数据

【讨论】:

我向你鞠躬。你的替代品是优越的。但是我有一点问题。你的代码给了我想要的东西,但是表格视图中的单元格“闪烁”了几次然后崩溃。 '*** -[__NSArrayM objectAtIndex:]:空数组的索引 0 超出范围'。知道这是怎么回事吗?我认为这是因为它一直在尝试更新。 你能用断点或 NSLog 证明 reload 只调用了一次吗?这就是我编写此代码的意图。另一个重要的一点是确认所有数据源方法都引用一个且只有一个数组,即我的代码中的 allPosts 数组。我现在可以看到我的建议在这方面不清楚。将编辑。 就是这样。我正在使用属性 NSMutableArray 代替“allPosts”。一旦我将我的财产分配给 allPosts,它就可以完美运行。你真是个了不起的家伙。实事求是。 很高兴听到。嘿只是一个简短的说明 - 如果帖子获取的数量太大,您可能需要一个云函数先聚合然后将它们全部返回。

以上是关于解析 iOS SDK:无法从数组中获取对象的主要内容,如果未能解决你的问题,请参考以下文章

IOS JSON解析包含多个数组

解析 JSON 文件(本地存储),从而快速创建对象数组

IOS - 从 Firebase 解析对象 - 下载完成前运行的代码

在通过改造获取对象数组时,错误无法解析方法

在 iOS 中解析 json 并将值添加到对象数组

parse.com - 如何使用 PHP SDK 从 parse.com 查询和获取类似数组的 json?