Objective-C中”NSRangeException”异常通常发生在用户试图访问数组、字符串等容器类型时,超出了其可访问的范围,造成越界访问的错误。该异常属于运行时异常,有以下两种情况会抛出该异常:
- 用户试图访问数组中不存在的元素,或者访问字符串的一个不存在的索引位置。
- 用户试图访问超出数组本身容量大小的元素,或者字符串的一个超出范围的索引位置。
而NSRangeException异常是一个比较常见的异常,下面分别介绍两种常见情况下该异常的处理方法:
情况一:访问不存在的元素
对于第一种情况,有两种处理方案:
处理方案一:
均避免使用[ ]下标访问数组,而是使用NSMutableArray的方法以避免数组越界异常。
示例代码如下:
//创建一个空数组:
NSMutableArray * arrayM = [NSMutableArray array];
[arrayM addObject:@1];
[arrayM addObject:@2];
//查找元素:
NSNumber * num = [arrayM objectAtIndex:3];
//输出
NSLog(@"%@", num);
以上代码中,由于访问了不存在的第3个元素,所以报运行时异常” Terminating app due to uncaught exception ‘NSRangeException’, reason: ‘ -[__NSArrayM objectAtIndex:]: index 3 beyond bounds [0 .. 1]'”
由此可知,使用[ ]下标访问数组时,需要仔细检查数组边界问题。而当使用NSMutableArray的方法时,越界的访问会导致程序缺省结束。所以,我们可以通过使用NSMutableArray的方法替代[ ]下标访问数组的方式来避免越界问题。
处理方案二:
在访问数组元素时,使用NSArray的方法objectAtIndex:来避免数组越界问题。
示例代码如下:
//创建一个空数组:
NSArray * array = @[@1, @2];
//查找元素:
NSNumber * num1 = [array objectAtIndex:0];
NSNumber * num2 = [array objectAtIndex:2];
//输出
NSLog(@"%@\n%@", num1, num2);
其中,我们先将两个数字添加到一个空数组中,然后分别使用objectAtIndex:方法来查找第0个元素和第2个元素。可以看到,运行时会出现如下错误提示信息:” Terminating app due to uncaught exception ‘NSRangeException’, reason: ‘ -[__NSArray0 objectAtIndex:]: index 2 beyond bounds for empty NSArray'”
重要提示:这种处理方案其实是不推荐的,因为其运行效率比使用NSMutableArray方法要低。
情况二:访问超出数组范围的元素
对于第二种情况,同样有两种处理方案:
处理方案一:
在访问数组元素时,需要保证下标在数组范围内。
示例代码如下:
//创建一个空数组:
NSArray * array = @[@1, @2, @3];
//查找元素:
NSNumber * num = [array objectAtIndex:10];
//输出
NSLog(@"%@", num);
在以上示例代码中,我们先创建了一个有三个元素的数组,并试图查找第十个元素。由于第十个元素超出了数组大小,运行时会出现如下错误提示信息:” Terminating app due to uncaught exception ‘NSRangeException’, reason: ‘ -[__NSArrayI objectAtIndex:]: index 10 beyond bounds [0 .. 2]'”
处理方案二:
在访问容器元素时,我们可以使用数组或字符串的长度来保证访问不超出容器的范围。
示例代码如下:
//创建一个空数组:
NSArray * array = @[@1, @2, @3];
NSUInteger index = 5;
//如果下标index在范围内,则查找元素,否则返回nil.
NSNumber * num;
if (index < [array count]) {
num = [array objectAtIndex:index];
}
NSLog(@"%@", num);
在以上示例代码中,我们创建了一个三个元素的数组,定义了一个下标index,如果下标index越过数组范围则不查找,否则在该数组中查找元素。
综上所述,报NSRangeException异常一般情况下是由于用户传入的索引超出了数组本身的大小限制,请谨慎使用。通过上述两种方案可以避免超出数组大小限制的情况发生,从而有效避免该异常的出现。