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處理的話要謹慎用!