使用NSArray时避免"越界"的完美方法是什么



我知道一些避免这种情况的方法,例如

if (index >= [_data count] || index < 0) return nil;
    return [_data objectAtIndex:index];

但是我应该这样做吗?或者关于这个话题还有其他解决方案吗?

首先,我想回应@rmaddy的评论,它位于:

没有通用的解决方案。每个案例都不一样。

也就是说,你可以使用其他技术:

firstObjectlastObject

这些方法将返回对象,如果没有,则返回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];
    }
}

相关内容

最新更新