2018年4月17日
1.效果
NSArray *arr = @[@1];
arr[1];
NSMutableArray *mArr = @[@2].mutableCopy;
mArr[1];
2018-04-17 10:36:46.924 quanqunahuli[13015:365882] 不可数组越界了
2018-04-17 10:36:49.197 quanqunahuli[13015:365882] 可变数组越界了
2.实现
#import
@interface NSArray (Wgarray)
@end
#import "NSArray+Wgarray.h"
#import
@implementation NSArray (Wgarray)
+ (void)load {
[super load];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 替换不可变数组中的方法 objectAtIndex
Method oldObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtIndex:));
Method newObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(newObjectAtIndex:));
method_exchangeImplementations(oldObjectAtIndex, newObjectAtIndex);
// 替换不可变数组中的方法 []调用的方法
Method objectAtIndexedSubscript = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtIndexedSubscript:));
Method newObjectAtIndexedSubscript = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(newObjectAtIndexedSubscript:));
method_exchangeImplementations(objectAtIndexedSubscript, newObjectAtIndexedSubscript);
// 替换可变数组中的方法 objectAtIndex
Method oldMObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(objectAtIndex:));
Method newMObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(newMutableObjectAtIndex:));
method_exchangeImplementations(oldMObjectAtIndex, newMObjectAtIndex);
// 替换可变数组中的方法 []调用的方法
Method oldMMutableObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(objectAtIndexedSubscript:));
Method newMMutableObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(newMutableObjectAtIndexedSubscript:));
method_exchangeImplementations(oldMMutableObjectAtIndex, newMMutableObjectAtIndex);
});
}
- (id)newObjectAtIndex:(NSUInteger)index {
if (index > self.count - 1 || !self.count) {
@try {
return [self newObjectAtIndex:index];
} @catch (NSException *exception) {
NSLog(@"不可数组越界了");
return nil;
} @finally {
}
} else {
return [self newObjectAtIndex:index];
}
}
- (id)newObjectAtIndexedSubscript:(NSUInteger)index {
if (index > self.count - 1 || !self.count) {
@try {
return [self newObjectAtIndexedSubscript:index];
} @catch (NSException *exception) {
NSLog(@"不可数组越界了");
return nil;
} @finally {
}
} else {
return [self newObjectAtIndexedSubscript:index];
}
}
- (id)newMutableObjectAtIndex:(NSUInteger)index {
if (index > self.count - 1 || !self.count) {
@try {
return [self newMutableObjectAtIndex:index];
} @catch (NSException *exception) {
NSLog(@"可变数组越界了");
return nil;
} @finally {
}
} else {
return [self newMutableObjectAtIndex:index];
}
}
- (id)newMutableObjectAtIndexedSubscript:(NSUInteger)index {
if (index > self.count - 1 || !self.count) {
@try {
return [self newMutableObjectAtIndexedSubscript:index];
} @catch (NSException *exception) {
NSLog(@"可变数组越界了");
return nil;
} @finally {
}
}
else{
return [self newMutableObjectAtIndexedSubscript:index];
}
}
@end
ps:如下用法ios系统9.3(含)以下会奔溃,初步定位为 是继承类导致替换方法混乱导致(按上面方法都写在父类里面解决)
#import
@interface NSArray (Wgarray)
@end
@interface NSMutableArray (Wgarray)
@end
#import "NSArray+Wgarray.h"
#import
@implementation NSArray (Wgarray)
+(void)load{
[super load];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = NSClassFromString(@"__NSArrayI");
Method oldMethod = class_getInstanceMethod(class, @selector(objectAtIndexedSubscript:));
Method newMethod = class_getInstanceMethod(class, @selector(wg_objectAtIndexedSubscript:));
if (oldMethod && newMethod) {
method_exchangeImplementations(oldMethod, newMethod);
}
});
}
- (id)wg_objectAtIndexedSubscript:(NSUInteger)index{
if (!self.count || self.count - 1 < index) {
TRACELOG(@"objectAtIndexedSubscript越界");
return nil;
}else{
id obj = [self wg_objectAtIndexedSubscript:index];
return obj;
}
}
@end
@implementation NSMutableArray (Wgarray)
+(void)load{
[super load];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//注意:他的确定可以从崩溃日至那里来确定,这个__NSArrayM类名的确认是从崩溃日志'*** -[__NSArrayM objectAtIndexedSubscript:]: index 6 beyond bounds [0 .. 2]'来确定的
Class class = NSClassFromString(@"__NSArrayM");
Method oldMethod = class_getInstanceMethod(class, @selector(objectAtIndexedSubscript:));
Method newMethod = class_getInstanceMethod(class, @selector(wg_objectAtIndexedSubscript:));
if (oldMethod && newMethod) {
method_exchangeImplementations(oldMethod, newMethod);
}
});
}
- (id)wg_objectAtIndexedSubscript:(NSUInteger)index{
if (!self.count || self.count - 1 < index) {
TRACELOG(@"objectAtIndexedSubscript可变数组越界");
return nil;
}else{
id obj = [self wg_objectAtIndexedSubscript:index];
return obj;
}
}
@end
如果您发现本文对你有所帮助,如果您认为其他人也可能受益,请把它分享出去。