Objective-C报”NSRangeException”异常的原因和解决办法

  • Post category:IOS

Objective-C中”NSRangeException”异常通常发生在用户试图访问数组、字符串等容器类型时,超出了其可访问的范围,造成越界访问的错误。该异常属于运行时异常,有以下两种情况会抛出该异常:

  1. 用户试图访问数组中不存在的元素,或者访问字符串的一个不存在的索引位置。
  2. 用户试图访问超出数组本身容量大小的元素,或者字符串的一个超出范围的索引位置。

而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异常一般情况下是由于用户传入的索引超出了数组本身的大小限制,请谨慎使用。通过上述两种方案可以避免超出数组大小限制的情况发生,从而有效避免该异常的出现。