【问题标题】:The "index 1 beyond bounds" error after JSON parsing and UITableView populatingJSON解析和UITableView填充后的“索引1超出范围”错误
【发布时间】:2013-01-29 16:05:42
【问题描述】:

这是我的代码(我需要从远程服务器上的源解析多个 JSON 文件),我需要使用每个解析的 SINGLE 值填充 UITableView:

单个 JSON 源(简单),位于 h**p://WWW.REMOTESERVERWITHJSONSOURCE.NET/A1:

{
  "id": 0001,
  "main": {
    "main1A": 100,
  },
  "main2": {
    "main2A": 200,
  },
  "url": "http...",
}

分配并初始化我的数组:

    - (void)viewDidLoad {

        // other stuff

        arrayA = [[NSMutableArray alloc] initWithObjects:@"A1", @"A2", nil]; //each object A1, A2...An is the single JSON source I need to parse
        arrayB = [[NSMutableArray alloc] initWithObjects:@"B1", @"B2", nil];
    }

解析方法:

- (void)LoadParse {

         main = [[NSMutableArray alloc] init];
         main2 = [[NSMutableArray alloc] init];

        for (int i=0; i < [arrayA count]; i++) {

            NSURL *url = [NSURL URLWithString:
                          [NSString stringWithFormat:
                           @"http://WWW.REMOTESERVERWITHJSONSOURCE.NET/%@",[arrayA objectAtIndex:i]]];

            NSURLRequest *request = [NSURLRequest requestWithURL:url];

            AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {

            NSMutableDictionary *arrayMain = [JSON valueForKey:@"main"];
            [main addObject:[arrayMain objectForKey:@"main1A"]];
            NSMutableDictionary *arrayMain2 = [JSON valueForKey:@"main2"];
            [main2 addObject:[arrayMain2 objectForKey:@"main2A"]];

            [table reloadData];
            [table scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];

            }

            failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON){

            }];

            [operation start];

            }
    }

UITableView 方法:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
     return [arrayA count];
}

// 其他方法

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:
                UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"];
    }

            cell.textLabel.font = [UIFont systemFontOfSize:12];
            cell.detailTextLabel.font = [UIFont systemFontOfSize:11];

            cell.textLabel.text = [NSString stringWithFormat:@"%@ - %@",[main objectAtIndex:indexPath.row],[main2 objectAtIndex:indexPath.row]]; // here I get error 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'

        cell.textLabel.backgroundColor = [UIColor clearColor];
        cell.detailTextLabel.backgroundColor = [UIColor clearColor];
        return cell;
}

错误:当我在arrayA 中仅分配和初始化一个对象时,一切正常:UITableView 填充一行并获取 main1 和 main2 的值;如果我在 arrayA 中分配并初始化多个对象,就像在这个例子中一样,应用程序崩溃并出现错误 signal SIGABRT: 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex :]: 索引 1 超出范围 [0 .. 0]' ...怎么了?请帮我排查问题,谢谢!

【问题讨论】:

    标签: xcode json parsing uitableview nsarray


    【解决方案1】:

    [添加]

    // Implement this for your numberOfRowsInSection
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        unsigned int mCount  = [main  count];
        unsigned int m2Count = [main2 count];
    
        return ( (mCount > m2Count) ? mCount : m2Count );
    }
    

    [附加 2]

    // Implement something like this within your cellForRowAtIndexPath routine
    bool mainExist  = ( (indexPath.row < [main count])  ? YES : NO );
    bool main2Exist = ( (indexPath.row < [main2 count]) ? YES : NO );
    
    if(YES == mainExist && YES == main2Exist){
    cell.textLabel.text = [NSString stringWithFormat:@"%@ - %@",[main objectAtIndex:indexPath.row],[main2 objectAtIndex:indexPath.row]];
    }else if(YES == main2Exist){
        cell.textLabel.text = [NSString stringWithFormat:@"___ - %@",[main2 objectAtIndex:indexPath.row]];
    }else{ // YES == mainExist
        cell.textLabel.text = [NSString stringWithFormat:@"%@ - ___",[main objectAtIndex:indexPath.row]];
    }
    

    看起来(从您的代码中)您正在使用 arrayA 来驱动您的单元格计数例程,但使用 main 和 main2 来填充。您不应该使用 main 和/或 main2 来生成您的细胞计数例程输出。

    看起来正在发生的事情是,当您以这种方式初始化时,arrayA 有 2 个元素,但由于数据的原因,main 和 main2 只填充了 1。因此,当您的单元格计数例程返回 2 时,单元格生成器例程是寻找 main 和 main2 索引 1,当索引只变为 0 时。

    这只是我直接从你的代码中看到的,如果你的代码或数据实际上不同,请告诉我。

    【讨论】:

    • 完全正确!如果我写 NSLog(@"%@",main) 和 NSLog(@"%@",main2) 每个“for ()”循环我只会得到 1 个值!那么我可以用代码做什么来解决问题呢?谢谢!
    • 在您的 numberOfRowsInSection 例程中使用 [main count] 和/或 [main2 count]。我可能仍然会返回 2 个计数中较大的一个,然后在您的 cellForRowAtIndexPath 例程中,有一个 if then 语句来测试 main 和 main2 是否有数据要输出,并且有 3 个不同的输出; 1) main 和 main2 都有数据 2) 只有 main 有数据 3) 只有 main2 有数据。
    • @Huxley - 这回答了你的问题吗?
    • 优雅的解决方案,@trumpetlicks,现在它可以工作了,而且只有你的第一个添加:你知道这个小问题吗?我认为应用程序需要一些时间来解析在arrayA中初始化的所有对象(我认为在它崩溃之前'因为在表reloadData之后没有足够的时间来加载数组),所以我看到表的ROWS比较一个一个... :) 正常吗?也许要一次看到所有行比较,我必须将 [table reloadData] 排除在 for() 循环之外?非常感谢!
    • 我正要问这个问题,但认为你有这个原因,这似乎不是问题所在。有两种不同的想法,将 reload 放在 for 循环中可能会让用户看到工作正在完成(即加载是实时发生的),第二种方法是在调用 reload 之前完成加载(即在 for 循环之后)。潜在的第 3 个选项是在 for 循环之外使用一个计时器,该计时器每秒左右调用一次 reload,第 4 个您可以使用加载图形让您的用户知道您仍在加载。
    猜你喜欢
    • 2019-06-04
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多