解析iOS版SDK:无法获取来自数组对象 [英] Parse iOS SDK: Not able to fetch Objects from Array

查看:122
本文介绍了解析iOS版SDK:无法获取来自数组对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这显示Facebook好友的数据表视图。数据存储在解析和我拉下来,并使用下面的查询存储在postArray的数据。我使用的NSLog检查postArray对象和我收到预期的效果。

什么情况是,我得到的的存储在postArray我的数据被设置到适当的标签,然后一些只是空的。正如我所说的,我做的NSLog postArray,这让我我想要的东西。但是,当我去设置数据,它不设置所有的数据,但只是一些。

问题1 - >我需要的所有数据,以便能够从数组访问,这不是让我

问题#2 - >据漫无是否加载的任何的在运行与否。如果我登录和注销其抛硬币是否也会加载任何东西。我的NSLog postArray,似乎它的数组为空的时候。我知道你在想什么 - 你得给我的东西比有时,但我真的不能把它的命中或错过

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

(和dispatch_async没有区别)

我一直在做=

  [FBRequest requestForMyFriends] startWithCompletionHandler:^(FBRequestConnection *连接,ID结果,NSError *错误){        如果(!错误){            friendDict =结果;            friendArray = friendDict [@数据];            对于(*的NSDictionary在friendObject friendArray){                friendIDs = [NSMutableArray的arrayWithObjects:[friendObject objectForKey:@ID],无]                PFQuery * postQuery = [PFQuery queryWithClassName:@邮报];
                [postQuery whereKey:@postedByID在containedin:friendIDs];
                [postQuery orderByAscending:@createdAt];
                [postQuery findObjectsInBackgroundWithBlock:^(NSArray中*的对象,NSError *错误){                    dispatch_async(dispatch_get_main_queue(),^ {                        postArray =物体;
                        [self.activityTableView reloadData];                    });                }];            }
        }        其他{            //有错误        }    }];


解决方案

我可以看到一对夫妇的方面,这code可能会出错。首先,它看起来像postArray得到每个内部查找完成时更换。第二,内发现的结构是有问题的,发射在快速依次连接N非同步调​​用,然后更新一个表,因为每个竞争。

考虑这个替代方案:我们构建可完成块非同步运行的一些方法。最简单的人做在 PFQuery 基于一个用户id 的帖子:

   - (无效)getPostsForId:(* NSString的)用户id withCompletion:(无效(^)(NSArray的*,NSError *)){完成    PFQuery * postQuery = [PFQuery queryWithClassName:@邮报];
    [postQuery whereKey:@postedByID在containedin:@ [用户id]];
    [postQuery orderByAscending:@createdAt];
    [postQuery findObjectsInBackgroundWithBlock:完成]。
}

的第二个是有趣的。这解决了非同步制作调用序列的问题,让一完成启动前下一个,只有调用它的建成块当所有完成。

它通过使用用户ID的数组作为一个待办事项列表和递归调用本身,收集在一个可变数组的结果做到这一点。当待办事项列表完整(空白),它调用它自己完成的块:

   - (无效)getPostsForIds:(NSArray的*)IDS的结果:(NSMutableArray的*)结果完成:(无效(^)(BOOL)){完成    如果(ids.count == 0)返回结束(YES);    * NSString的用户id = IDS [0];
    的NSArray * remainingIds = [IDS subarrayWithRange:NSMakeRange(1,ids.count-1)];    [个体经营getPostsForId:用户id withCompletion:^(* NSArray的帖子,NSError *错误){
        如果(!错误){
            [结果addObjectsFromArray:帖子];
            [个体经营getPostsForIds:remainingIds结果:结果完成:];
        }其他{
            完成(NO);
        }
    }];
}

现在你开始可以简化方法。得到FB好友名单,建立自己的ID数组,并调用上面你神奇的功能:

   - (无效){getFriendsPosts    [FBRequest requestForMyFriends] startWithCompletionHandler:^(FBRequestConnection *连接,ID结果,NSError *错误){
        如果(!错误){
            friendDict =结果;
            friendArray = friendDict [@数据];            NSMutableArray里* IDS = [NSMutableArray的阵列]            对于(*的NSDictionary在friendObject friendArray){
                [IDS ADDOBJECT:[friendObject objectForKey:@身份证]];
            }
            NSMutableArray里* allPosts = [NSMutableArray的阵列]
            [个体经营getPostsForIds:IDS的结果:allPosts完成:^(BOOL成功){                //编辑 - 一定要使用所产生的allPosts作为你的数据源
                self.theModelForMyTable = allPosts;                [self.activityTableView reloadData];
                //如果!成功做了一个警报或东西
            }];
        }
    }];
}

数据源的方法应该仅指表模型,因此,例如numberOfRowsInSection应该回答 self.theModelForMyTable.count 和的cellForRowAtIndexPath应始终得到数据从配置单元 self.theModelForMyTable [indexPath.row]

I have a table view which displays Facebook friend's data. Data is stored on Parse and I'm pulling it down and storing the data in "postArray" using the following query. I have used NSLog to check postArray object's and I am getting the desired results.

What happens is that I get sum of my data stored in postArray to be set to the appropriate labels and then some are just left empty. As I said, I did NSLog postArray and it gives me what I wanted. But when I go to set the data, it doesn't set all the data but just some.

Problem #1--> I need all of the data to be able to be accessible from the array and it's not letting me.

Problem #2 --> It is hit or miss whether it loads anything at runtime or not. If I log in and log out its a coin flip whether it will even load anything. I NSLog postArray and it seems it the array is empty sometimes. I know what you are thinking - "You got to give me something better than "sometimes", but I really can't. It's hit or miss.

Please help me out and tell me what's going on with it!

(and the dispatch_async makes no difference)

What I've been doing =

    [[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

        }

    }];

解决方案

I can see a couple ways this code can go wrong. First, it looks like postArray gets replaced each time the inner find completes. Second, the structure of the inner find is problematic, launching N asynch calls in rapid succession, then updating a table as each competes.

Consider this alternative: we build a few methods that can run asynch with completion blocks. The simplest one does the PFQuery for posts based on a userId:

- (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];
}

The second one is the interesting one. This solves the problem of making a sequence of asynch calls, letting one finish before launching the next, and only invoking it's completion block when all are complete.

It does this by using the array of user ids as a to-do list and calling itself recursively, collecting the results in a mutable array. When the to-do list is complete (empty), it calls it's own completion block:

- (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);
        }
    }];
}

Now the method you started with can be simplified. Get the friends list from FB, build an array of their ids, and call your magic function above:

- (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
            }];
        }
    }];
}

The datasource methods should refer only to the table model, so for example numberOfRowsInSection should answer self.theModelForMyTable.count and cellForRowAtIndexPath should always get the data to configure the cell from self.theModelForMyTable[indexPath.row]

这篇关于解析iOS版SDK:无法获取来自数组对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆