我知道一些避免这种情况的方法,例如
if (index >= [_data count] || index < 0) return nil;
return [_data objectAtIndex:index];
但是我应该这样做吗?或者关于这个话题还有其他解决方案吗?
首先,我想回应@rmaddy的评论,它位于:
没有通用的解决方案。每个案例都不一样。
也就是说,你可以使用其他技术:
firstObject
和lastObject
这些方法将返回对象,如果没有,则返回nil
。这些方法永远不会抛出异常。
快速枚举
您可以使用快速枚举,而无需检查索引:
NSArray *myStrings = @[@"one", @"two"];
for (NSString *thisString in myStrings) {
NSLog(@"A string: %@", thisString);
}
安全类别
如果你发现自己经常这样做,你可以在NSArray
上添加一个类别:
- (id)safeObjectAtIndex:(NSUInteger)index {
if (index >= [self count] || index < 0) return nil;
return [self objectAtIndex:index];
}
如果您不熟悉类别,请参见自定义现有类。
这样做的一个缺点是可能更难在代码中找到错误。
在苹果库中NSArray对象AtIndex方法:
objectAtIndex:
Returns the object located at the specified index.
- (id)objectAtIndex:(NSUInteger)index
Parameters
index
An index within the bounds of the array.
Return Value
The object located at index.
您可以使用"NSUInteger index;",因此可以省略"if(index<0)"。
在我看来,如果你需要为其他人提供一些接口,你可能需要添加这些代码来避免"越界"。但是,如果你的代码只是为自己工作,你就不需要做这些事情,因为大多数时候你需要的是数组中的一个对象,而不是nil。如果索引超出了界限,那么一定有一些逻辑错误需要修复。让异常消失并找到您的bug。
U可以切换objectAtIndex
方法,在调用objectAtIndex
之前,调用类似"custom_objectAtIndex"的方法来检查是否越界。
+ (void)load{
Method method1 = class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(objectAtIndex:));
Method method2 = class_getInstanceMethod(objc_getClass("__NSArrayI"),@selector(custom_objectAtIndex:));
method_exchangeImplementations(method1, method2);
}
- (id)custom_objectAtIndex:(NSUInteger)index{
NSLog(@"~~~~~~~:%ld",count);
if (index >= self.count) {
return @"out of bounds";
} else {
return [self custom_objectAtIndex:index];
}
}