在viewDidLoad中访问数组报错:index 1超出空数组边界
问题分析与解决方案
嘿,这个问题我之前也碰到过!咱们先拆解一下问题根源,再一步步解决它~
核心原因:数组加载时机不匹配
你看到的NSRangeException异常已经说得很清楚了:在viewDidLoad里调用取值函数时,你的NSMutableArray还是空数组,但你却尝试访问索引1的元素,直接触发了越界错误。
而按钮点击时能正常运行,说明按钮触发的时机,数组已经被正确填充了数据——这两种场景的核心差异,就是数组的加载状态不一样。大概率你的数据加载是异步操作(比如网络请求、本地文件异步读取),viewDidLoad执行时异步任务还没完成,数组自然是空的;而用户点击按钮时,异步任务已经结束,数组里已经有内容了。
具体解决步骤
1. 调整取值函数的调用时机
把取值函数的调用,放到数据加载完成的回调逻辑里,确保数组已经有数据了再去访问元素。举个异步加载的示例:
- (void)viewDidLoad { [super viewDidLoad]; // 先启动数据加载任务 [self loadJSONDataAsync]; } - (void)loadJSONDataAsync { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 模拟网络请求/本地JSON读取 NSArray *fetchedJSONData = [self fetchJSONFromSource]; dispatch_async(dispatch_get_main_queue(), ^{ // 数据加载完成,填充数组 self.dataArray = [NSMutableArray arrayWithArray:fetchedJSONData]; // 现在再调用取值函数,就不会崩溃了 [self showDataAtIndex:1 onButton:self.targetButton]; }); }); }
2. 给取值函数加上安全校验(必备!)
不管什么时候访问数组元素,都应该先做边界检查,避免因为意外情况(比如数据加载失败、返回的JSON数据元素数量不足)导致崩溃。修改你的取值函数:
- (void)showDataAtIndex:(NSInteger)index onButton:(UIButton *)button { // 先做安全校验:数组存在、非空、索引在有效范围内 if (!self.dataArray || self.dataArray.count == 0 || index < 0 || index >= self.dataArray.count) { NSLog(@"警告:数组为空或索引越界"); [button setTitle:@"无数据" forState:UIControlStateNormal]; return; } // 安全取值并显示 id targetData = self.dataArray[index]; // 假设数据是字符串类型,根据你的实际JSON结构调整 [button setTitle:targetData forState:UIControlStateNormal]; }
总结一下
- 崩溃的本质是在数组为空时访问了越界索引
- 两种场景的差异是因为
viewDidLoad时数组未加载完成,按钮点击时数组已就绪 - 最终方案是:确保数据加载完成后再调用取值函数,同时给数组访问加上边界校验,双管齐下避免崩溃。
内容的提问来源于stack exchange,提问作者user9713861
相关产品推荐
相关产品推荐

