-4

我第一次在 Objective-C 中试验 JSON。

这是我的终端应用程序的代码:

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://itunes.apple.com/search?term=harry&country=us"]];
        NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
        NSError *jsonParsingError = nil;
        NSArray *publicTimeline = [NSJSONSerialization JSONObjectWithData:response options:0 error:&jsonParsingError];
        NSDictionary *list;
        for(int i=0; i<[publicTimeline count];i++)
        {
            list = [publicTimeline objectAtIndex:i];
            NSLog(@"Statuses: %@", [list objectForKey:@"trackName"]);
        }
    }
    return 0;
}

这是我得到的错误:

2013-09-11 20:58:55.524 Tweets[7291:303] -[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x100391d60
2013-09-11 20:58:55.526 Tweets[7291:303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary objectAtIndex:]: unrecognized selector sent to instance 0x100391d60'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff91688b06 __exceptionPreprocess + 198
    1   libobjc.A.dylib                     0x00007fff8bf8a3f0 objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff9171f40a -[NSObject(NSObject) doesNotRecognizeSelector:] + 186
    3   CoreFoundation                      0x00007fff9167702e ___forwarding___ + 414
    4   CoreFoundation                      0x00007fff91676e18 _CF_forwarding_prep_0 + 232
    5   Tweets                              0x0000000100000d1a main + 378
    6   libdyld.dylib                       0x00007fff908e67e1 start + 0
)
libc++abi.dylib: terminate called throwing an exception

怎么了?我完美地遵循了一个教程,但我是唯一一个得到错误的人。

4

1 回答 1

1

我运行了你的代码。我的结果与你的不一致。我没有崩溃,但我确实收到(null)了最后的NSLog电话。

是的,您应该检查+[NSJSONSerialization JSONObjectWithData:options:error]. 正如@HotLicks 非常正确地向您指出的那样,如果您得到的结果为零,则检查错误对象可以揭示出问题所在的重要线索。

但在这种情况下,它是学术性的,因为结果(再次,在我的情况下)不是nil. 然而,真正的问题是您似乎不了解您的数据架构。jsonObject是一本字典,但它只有两个键,resultsand resultCount,这就是你从[jsonObject objectForKey:@"trackName"];得到 nil 的原因。trackName不是关键之一。

然而,你得到的那两个钥匙应该告诉你很多。它告诉我足够的尝试:

NSArray *results = [jsonObject objectForKey:@"results"];
NSDictionary *dictionary = [results objectAtIndex:0];
id latestLoans = [dictionary objectForKey:@"trackName"];

并得到了一个结果:

Harry Potter and the Deathly Hallows - Part 1

换句话说,我只是简单地得到数组中的第一个字典 for results,然后向它询问它拥有的对象 for trackName

由于您最初要求的是一个数组,我猜您想要该特定键的所有值,所以如果您使用这个:

NSArray *latestLoans = [jsonObject valueForKeyPath:@"results.trackName"];

trackName它提供了与键下字典中的键对应的 50 个值的列表results

编辑:

您真正需要做的另一件事是通过在调用其他任何内容之前检查它来保护自己免受nil从您的调用返回的可能性。-[NSData initWithContentsOfURL:]仅此一项并不能解决您无法获得响应的问题,但可以防止您崩溃。如果您确实收到nil了 ,请务必检查您返回的错误对象的domaincode属性,以了解发生了什么问题。

于 2013-09-10T16:38:07.327 回答