IOS 中runtime 不可变数组__NSArray0 和__NSArrayI
大家可能都遇到过项目中不可变数组避免数组越界的处理:runtime,然而有时候并不能解决所有的问题,因为类簇不一样
#import "NSArray+Security.h"
#import "NSObject+Swizzling.h"
@implementation NSArray (Security)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[objc_getClass("__NSArray0") methodSwizzlingWithOriginalSelector:@selector(objectAtIndex:) bySwizzledSelector:@selector(safeObjectAtIndex:)];
});
}
- (id)safeObjectAtIndex:(NSUInteger)index {
if (self.count == 0) {
NSLog(@"%s can't get any object from an empty array", __FUNCTION__);
return nil;
}
if (index > self.count) {
NSLog(@"%s index out of bounds in array", __FUNCTION__);
return nil;
}
return [self safeObjectAtIndex:index];
}
@end
但是不同的创建数组的方法导致不同的类簇(其实也就是不同的指针),下面我们就看
NSArray *arr1 = @[@"1",@"2"];
NSArray *arr2 = [[NSArray alloc]init];
NSArray *arr2 = [[NSArray alloc]initwithobjocts:@"1",nil];
NSArray *arr3 = [NSArray alloc];
NSMutbleArray *arr4 = [NSMutbleArray array];
你会发现:
1、arr2类名叫_NSArray0
2、未init的arr3,类名叫做_NSPlaceHolderArray;
3、初始化后的可变数组类名都叫_NSArrayM;
4、初始化后的不可变数组类名都叫_NSArrayI.
所以做runtime处理的话要谨慎用!