无法从JSON NSDictionary获取对象

时间:2013-06-25 18:34:21

标签: ios objective-c cocoa-touch

当我将JSON转换为NSDictionary时,请调用ObjectForKey:我收到错误:-[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0xa9801d0

我的转换代码:

NSError *error;

NSData *responseData = [NSData dataWithContentsOfURL:dataURL];

NSDictionary *json = [NSJSONSerialization
                      JSONObjectWithData:responseData

                      options:kNilOptions
                      error:&error];

NSLog(@"%@",json);
//The exeption is hilighted here:
NSArray *objects = [[json objectForKey:@"data"] objectForKey:@"children"];

这是文件:

 {
    data =         {
        after = "<null>";
        before = "<null>";
        children =             (
                            {
                data =                     {
                    "approved_by" = "<null>";
                    author = Jonovono;
                    "author_flair_css_class" = "<null>";
                    "author_flair_text" = "<null>";
                    "banned_by" = "<null>";
                    clicked = 0;
                    created = 1371955129;
                    "created_utc" = 1371926329;
                    distinguished = "<null>";
                    domain = "self.redditdev";
                    downs = 1;
                    edited = 0;
                    hidden = 0;
                    id = 1gv8g1;
                    "is_self" = 1;
                    likes = "<null>";
                    "link_flair_css_class" = "<null>";
                    "link_flair_text" = "<null>";
                    media = "<null>";
                    "media_embed" =                         {
                    };
                    name = "t3_1gv8g1";
                    "num_comments" = 2;
                    "num_reports" = "<null>";
                    "over_18" = 0;
                    permalink = "/r/redditdev/comments/1gv8g1/rate_limiting_on_commenting/";
                    saved = 0;
                    score = 4;
                    selftext = "Can't really find anyone else having this issue. I am using this ruby library for reddit api wrapper: https://github.com/paradox460/snoo\n\nIt seems when I comment only the first one goes through, and any others fail. It does not seem to return a message, but I am guessing it's because of the message that only comment so much in so much time. How can I get around that? Or is something else causing it? Thanks.";
                    "selftext_html" = "&lt;!-- SC_OFF --&gt;&lt;div class=\"md\"&gt;&lt;p&gt;Can&amp;#39;t really find anyone else having this issue. I am using this ruby library for reddit api wrapper: &lt;a href=\"https://github.com/paradox460/snoo\"&gt;https://github.com/paradox460/snoo&lt;/a&gt;&lt;/p&gt;\n\n&lt;p&gt;It seems when I comment only the first one goes through, and any others fail. It does not seem to return a message, but I am guessing it&amp;#39;s because of the message that only comment so much in so much time. How can I get around that? Or is something else causing it? Thanks.&lt;/p&gt;\n&lt;/div&gt;&lt;!-- SC_ON --&gt;";
                    subreddit = redditdev;
                    "subreddit_id" = "t5_2qizd";
                    thumbnail = "";
                    title = "Rate limiting on commenting?";
                    ups = 5;
                    url = "http://www.reddit.com/r/redditdev/comments/1gv8g1/rate_limiting_on_commenting/";
                };
                kind = t3;
            }
        );
        modhash = 6dviotq5igca155758e9e858f1d863870f1b5296d9d571d45d;
    };
    kind = Listing;
},
    {
    data =         {
        after = "<null>";
        before = "<null>";
        children =             (
                            {
                data =                     {
                    "approved_by" = "<null>";
                    author = pipeep;
                    "author_flair_css_class" = "<null>";
                    "author_flair_text" = "<null>";
                    "banned_by" = "<null>";
                    body = "New accounts are severely rate limited on comment speed to prevent spamming. Once you accumulate some karma, that goes down rather quickly. I've found that my bot with a few thousand karma is able to post a few times a minute at peek without any problems.\n\nThe API returns an error if you post too quickly (Probably `RATELIMIT` or `SUBREDDIT_RATELIMIT`; I don't remember). You can either drop those comments or put them in a queue and retry later, hoping that your queue doesn't get too long.";
                    "body_html" = "&lt;div class=\"md\"&gt;&lt;p&gt;New accounts are severely rate limited on comment speed to prevent spamming. Once you accumulate some karma, that goes down rather quickly. I&amp;#39;ve found that my bot with a few thousand karma is able to post a few times a minute at peek without any problems.&lt;/p&gt;\n\n&lt;p&gt;The API returns an error if you post too quickly (Probably &lt;code&gt;RATELIMIT&lt;/code&gt; or &lt;code&gt;SUBREDDIT_RATELIMIT&lt;/code&gt;; I don&amp;#39;t remember). You can either drop those comments or put them in a queue and retry later, hoping that your queue doesn&amp;#39;t get too long.&lt;/p&gt;\n&lt;/div&gt;";
                    created = 1371970411;
                    "created_utc" = 1371941611;
                    distinguished = "<null>";
                    downs = 0;
                    edited = 0;
                    gilded = 0;
                    id = cao9eaf;
                    likes = "<null>";
                    "link_id" = "t3_1gv8g1";
                    name = "t1_cao9eaf";
                    "num_reports" = "<null>";
                    "parent_id" = "t3_1gv8g1";
                    replies =                         {
                        data =                             {
                            after = "<null>";
                            before = "<null>";
                            children =                                 (
                                                                    {
                                    data =                                         {
                                        "approved_by" = "<null>";
                                        author = Jonovono;
                                        "author_flair_css_class" = "<null>";
                                        "author_flair_text" = "<null>";
                                        "banned_by" = "<null>";
                                        body = "Alright, thanks. Good to know it goes down with karma. So karma is good for something.";
                                        "body_html" = "&lt;div class=\"md\"&gt;&lt;p&gt;Alright, thanks. Good to know it goes down with karma. So karma is good for something.&lt;/p&gt;\n&lt;/div&gt;";
                                        created = 1372014449;
                                        "created_utc" = 1371985649;
                                        distinguished = "<null>";
                                        downs = 0;
                                        edited = 0;
                                        gilded = 0;
                                        id = caoivdj;
                                        likes = "<null>";
                                        "link_id" = "t3_1gv8g1";
                                        name = "t1_caoivdj";
                                        "num_reports" = "<null>";
                                        "parent_id" = "t1_cao9eaf";
                                        replies = "";
                                        "score_hidden" = 0;
                                        subreddit = redditdev;
                                        "subreddit_id" = "t5_2qizd";
                                        ups = 1;
                                    };
                                    kind = t1;
                                }
                            );
                            modhash = 6dviotq5igca155758e9e858f1d863870f1b5296d9d571d45d;
                        };
                        kind = Listing;
                    };
                    "score_hidden" = 0;
                    subreddit = redditdev;
                    "subreddit_id" = "t5_2qizd";
                    ups = 1;
                };
                kind = t1;
            }
        );
        modhash = 6dviotq5igca155758e9e858f1d863870f1b5296d9d571d45d;
    };
    kind = Listing;
}
)

我需要能够从JSON获取任何对象,但我不知道为什么会抛出此异常。

4 个答案:

答案 0 :(得分:3)

您是否在您提供的JSON输出结尾处看到了孤独的)。如果您查看来自Xcode的实际日志,您可能会发现有一个匹配的(您忘记复制并粘贴到您的问题中。

您实际拥有的是JSON对象,它是一个数组而不是字典,所以当您尝试获取键的值时,编译器会告诉您该数组不响应该消息。

这应该可以帮助你解压缩你的JSON对象,你需要遍历一个字典数组来提取你需要的值。

答案 1 :(得分:1)

我将通过添加一小段代码来完成@Abizem答案,因为我发现你是初学者(我没有任何问题)而且我知道当你开始编程或新语言时,代码片段非常有用(不会计算谷歌充满了JSON解析教程,并且在解析时SO充满了你的问题unrecognized selector。)

因此,只要你有一个以(开头的JSON,就意味着JSON是一个数组,如果JSON以{开头,那么JSON就是一个字典。

为了从JSON数组中获取对象,您必须迭代它。 JSON包含的对象可以是字典或数组。

因此,如果你的数组只有字典,你应该使用:

for(NSDictionary *contentDictionary in yourJSONObject) {
  //do stuffs with your dictionary 
}

如果您的JSON中只有数组,则应使用:

for(NSArray *contentArray in yourJSONObject) {
//do stuffs with your dictionary 
}

如果您的JSON中同时包含数组和词典,则应使用:

for(id unknownType in yourJSONObject) {
   if([unknownType isKindOfClass:[NSDictionary class]]) {
       NSDictionary *dict = (NSDictionary*)unknownType;
   }
   else if ([unknownType isKindOfClass:[NSArray class]]{
       NSArray *array = (NSArray *)unknownType;
   }   
}

如果您的JSON是字典,那么您可以使用NSDictionary方法获取正确的值:

  [dictJSON objectForKey:@"myKey"];

答案 2 :(得分:0)

JSON是一个数组而不是字典。在将其作为字典访问之前,从数组中获取第一个元素。

答案 3 :(得分:0)

您的对象json是您尝试访问的NSArray,如NSDictionaryobjectForKey: