在開發(fā)中我們經(jīng)常遇到數(shù)組越界造成程序crash,我們可以選擇在使用數(shù)組時(shí)添加判斷,但是這種方法比較麻煩,因?yàn)槟沩?xiàng)目中如果用到一百個(gè)數(shù)組,你就要添加一百次判斷,這是最愚笨的方法,或者有的同學(xué)會使用下面這種方法
//建一個(gè)NSArray的分類,在分類里寫入下面方法
- (id)objectAtIndexCheck:(NSUInteger)index{
if (index>self.count-1) {
NSAssert(NO, @"index beyond the boundary");
return nil;
}else{
return [self objectAtIndex:index];
}
}
使用
NSArray *array = @[@"1",@"2",@"3"];
NSLog(@"-------%@--",[array objectAtIndexCheck:4]);
這個(gè)方法有一個(gè)缺點(diǎn)就是直接用下標(biāo)取值是一樣會crash
如果是用runtime處理此種問題,不管你用objectAtIndex或者直接用下標(biāo)array[4]都不會出現(xiàn)問題
#import "NSArray+Bundary.h"
#import <objc/runtime.h>
@implementation NSArray (Bundary)
+ (void)load
{
//使用單例模式
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//方法的selector用于表示運(yùn)行時(shí)方法的名字。
//Objective-C在編譯時(shí),會依據(jù)每一個(gè)方法的名字、參數(shù)序列,生成一個(gè)唯一的整型標(biāo)識(Int類型的地址),這個(gè)標(biāo)識就是SEL
SEL newSel = @selector(newObjectAtIndex:);
SEL originalSel = @selector(objectAtIndex:);
//使用runtime方法拿到實(shí)例中的方法
Method newMethod = class_getInstanceMethod(self, newSel);
Method originalMethod = class_getInstanceMethod(self, originalSel);
//交換方法
method_exchangeImplementations(originalMethod, newMethod);
});
}
- (id)newObjectAtIndex:(NSUInteger)index{
if (index > self.count-1) {
NSAssert(NO, @"index beyond the boundary");
return nil;
}else{
return [self newObjectAtIndex:index];
}
}
@end
使用
NSArray *array = @[@"1",@"2",@"3"];
NSLog(@"%@",array[4]);
這段代碼主要是運(yùn)用到runtime的方法交換函數(shù),讓系統(tǒng)自帶的objectAtIndex方法和自己定義的newObjectAtIndex方法交換,然后再newObjectAtIndex方法里面處理判斷是否越界
[self newObjectAtIndex:index]這個(gè)方法不會循環(huán)調(diào)用,因?yàn)槲覀円呀?jīng)將objectAtIndex替換為newObjectAtIndex