【问题标题】:Empty array error when parsing JSON to UILabel将 JSON 解析为 UILabel 时出现空数组错误
【发布时间】:2014-03-20 11:15:51
【问题描述】:

我正在尝试从我的服务器上的 JSON 文件中解析一些文本。我从文件中解析了三个不同的值:"value1":"some_value""value2":"some_value""value3":"some_value"

我声明了一个名为 statsHome 的 NSMutableArray,我在 viewDidLoad 方法中对其进行了初始化,如下所示:statsHome = [[NSMutableArray alloc] init];

问题是我初始化数组后,需要设置一个NSDictionary。如果我要在表格视图中这样做,我会写:

NSDictionary *stats = [self.statshome objectAtIndex:indexPath.row];

但我没有将这些值解析到表格视图中。我想将它们解析为 UILabel。所以我尝试的是声明新的NSUInteger。因为我不能在 viewDidLoad 方法中使用indexPath.row。我称它为statsIndex

但是当我启动应用程序时它崩溃并给我这个错误消息:Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'

其余代码如下所示:

@interface DEMOHomeViewController () {
    NSUInteger statsIndex;
}
@end

@implementation DEMOHomeViewController
@synthesize statsHome;
@synthesize twitterFollowers;
@synthesize facebookLikes;
@synthesize instagramFollowers;

- (void)viewDidLoad
{
    [super viewDidLoad];  

    statsHome = [[NSMutableArray alloc] init];

    NSDictionary *stats = [self.statsHome objectAtIndex:statsIndex];

    value1.text = [stats objectForKey:@"value1"];
    value2.text = [stats objectForKey:@"value2"];
    value3.text = [stats objectForKey:@"value3"];

    NSURL *url1 = [[NSURL alloc] initWithString:@"the-json-file-with-the-values.php/file.json"];
    NSURLRequest *request1 = [[NSURLRequest alloc] initWithURL:url1];

    AFJSONRequestOperation *operation1 = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        self.statsHome = [[NSArray alloc] initWithArray:JSON];
        [self.activityIndicatorView stopAnimating];

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
    }];

    [operation1 start];

}

@end

【问题讨论】:

  • 在第二行中,你的 alloc/init statsHome,(与self.statsHome?)是空的,你直接尝试从中获取一个值(objectAtIndex:statsIndex),所以,那就是它崩溃是正常的。
  • 那我应该怎么做呢? @Larme
  • 我会等到我得到我的值(通过 JSON 请求),然后再设置标签。
  • 但是我该怎么做呢? @Larme

标签: ios objective-c json parsing


【解决方案1】:

错误是正确的:您试图在设置数据之前从数组中获取数据。您应该在下面的代码中执行类似的操作。

- (void)viewDidLoad
{
    [super viewDidLoad];  

    NSURL *url1 = [[NSURL alloc] initWithString:@"the-json-file-with-the-values.php/file.json"];
    NSURLRequest *request1 = [[NSURLRequest alloc] initWithURL:url1];

    AFJSONRequestOperation *operation1 = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        [self.activityIndicatorView stopAnimating];
        [self updateDataWithJSON:JSON]; // <- Here we will update our data
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        NSLog(@"Request Failed with Error: %@, %@", error, error.userInfo);
    }];

    [operation1 start];

}

- (void)updateDataWithJSON:(id)JSON 
{
    self.statsHome = [[NSArray alloc] initWithArray:JSON];

    NSDictionary *stats = [self.statsHome objectAtIndex:statsIndex];

    value1.text = [stats objectForKey:@"value1"];
    value2.text = [stats objectForKey:@"value2"];
    value3.text = [stats objectForKey:@"value3"];
}

让我给你一个建议。似乎您的 statsIndex 在您的应用程序的其他部分初始化。在这种情况下,最好在每次访问此数组时检查 statsIndex 是否适合数组长度。否则在某些情况下可能是应用程序崩溃的原因:例如,您将数组放在其他控制器中,并且它有 10 个元素。您选择最后一个元素,但在 DEMOHomeViewController 的 viewDidLoad 中重新加载请求。而此时数组只有 9 个元素(最后一个元素已被其他人删除)。 -> 崩溃

【讨论】:

  • 酷。但是现在,当我启动应用程序时,标签变空了。似乎什么都没有被解析...@anatoliy_v
  • @tracifycray 您可以隐藏标签,直到收到数据并在 updateDataWithJSON: 方法中取消隐藏。这是请求/响应的常见做法......
  • 但是我尝试等待超过 8 分钟,标签中没有出现任何内容... 有问题@anatoliy_v
  • 您可以检查以下几项以获得答案:1) 您收到回复了吗? 2) 响应的 JSON 是什么? 3) 是否调用了 updateDataWithJSON: 4) 是否将 value1.hidden = NO 添加到 updateDataWithJSON: 中?
  • 嗯,想不通。有邮寄地址吗?
【解决方案2】:

NSURL *url = [NSURL URLWithString: [NSString stringWithFormat:@"url"];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

[request setHTTPMethod:@"GET"];

[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

NSString *authStr = [NSString stringWithFormat:@"%@:%@", @"usernmae", @"password"];

NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];

NSString *authValue = [NSString stringWithFormat:@"Basic %@", [authData base64EncodedStringWithOptions:0]];

NSLog(@"%@",authValue);//

[request setValue:authValue forHTTPHeaderField:@"Authorization"];

[request setURL:url];
NSLog(@"%@",url);

NSError *error;

NSHTTPURLResponse *response;

NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

NSLog(@"Response code: %ld", (long)[response statusCode]);

NSLog(@"Data is %@",data);

【讨论】:

  • 如果您在 LOG 中获取数据。那你尽自己的一份力
  • 所有这些代码都应该在 viewDidLoad 方法中吗? @VmC501
  • 是的,您可以在视图中使用加载 json url 加载方法.. 或者您可以使用视图将出现方法。
  • [请求 setHTTPMethod:@"GET"];不要忘记设置 Http 方法。如果你不设置任何方法,它会返回空的 json 响应
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 2016-12-18
  • 2015-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-20
相关资源
最近更新 更多