Tommy(凌飞)的专栏

常见crash数组越界

这里主要由NSArray或者NSMutableArray访问了不在范围内的对象造成的。对于Inmutable数组基本就涉及到一个objectAtIndex:。

NSArray *array = @[@”test”]; id object = array[1];//抛出异常1.

而对于Mutable数组有修改和删除就主要涉及到setObject:atIndex,insertObject:atIndex:和removeObject:atIndex:来着。

NSMutableArray *mArray = [NSMutableArray arrayWithArray:@[@”test”]];[mArray insertObject:@”asdf” atIndex:2]; //抛出异常 2.[mArray removeObejctAtIndex:2]; //异常3.插入nil对象这类问题基本上是出现在数组、字典的初始化中,或者在插入对象时出现。id obj = nil;NSArray *array = @[obj,@”test”]; //异常 1NSString *key = nil;NSString *value = nil;NSDictionary *dict = @{key:value}; //异常 2无法识别的selector其他异常

针对上面的2个问题,我这里是通过category+swizzle的方式进行的。由于无法识别selector,还没有还一点的正常途径来解决。所以就不说了。这里就弄几段代码。

@implementation NSObject (KLSwizzle)+ (void) kl_swizzleInstanceSelector:(SEL)originalSelectorwithNewSelector:(SEL)newSelector{Method originalMethod = class_getInstanceMethod(self, originalSelector);Method newMethod = class_getInstanceMethod(self, newSelector);BOOL methodAdded = class_addMethod([self class],originalSelector,method_getImplementation(newMethod),method_getTypeEncoding(newMethod));if (methodAdded){class_replaceMethod([self class],newSelector,method_getImplementation(originalMethod),method_getTypeEncoding(originalMethod));}else {method_exchangeImplementations(originalMethod, newMethod);}}+ (void)kl_swizzleClassSelector:(SEL)originalSelectorwithNewSelector:(SEL)newSelector{Method originalMethod = class_getClassMethod(self, originalSelector);Method newMethod = class_getClassMethod(self, newSelector);method_exchangeImplementations(originalMethod, newMethod);}@end@implementation NSArray (KLException)+ (void)load{static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{Class cls = [[self array] class];[cls kl_swizzleInstanceSelector:@selector(objectAtIndex:) withNewSelector:KLHookedSel(objectAtIndex:)];[self kl_swizzleClassSelector:@selector(arrayWithObjects:count:) withNewSelector:KLHookedSel(arrayWithObjects:count:)];});}- (id)KLHookedMethod(objectAtIndex:(NSUInteger)index){__autoreleasing id instance = nil;if([self checkRange:index]){@try{instance = [self KLHookedMethod(objectAtIndex:)index];}@catch (NSException *exception) {KLLogError(@”exception:%@”,exception);}}else{KLLogError(@”catch out of range:%lul in %@ “,(unsigned long)index,self);}return instance;}- (BOOL)checkRange:(NSUInteger)index{return [self count] > index;}+ (void) _kl_removeObjectFromArray:(const id [])objects at:(NSUInteger) index count:(NSUInteger)cnt{__unsafe_unretained id* objs = (__unsafe_unretained id*) objects;for(NSUInteger i=index;i<cnt&&(i+1)<cnt;++i){objs[i] = objs[i+1];}}+ (instancetype)KLHookedMethod(arrayWithObjects:(const id [])objects count:(NSUInteger)cnt){NSUInteger count = cnt;for(NSUInteger i = 0; i < count; ++i){if(!objects[i]) {KLLogError(@”insert nil at %d”,i);[self _kl_removeObjectFromArray:objects at:i count:count–];}}return [self KLHookedMethod(arrayWithObjects:objects count:count)];}@end@implementation NSDictionary (KLException)+ (void)load{static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{[self kl_swizzleClassSelector:@selector(dictionaryWithObjects:forKeys:count:) withNewSelector:KLHookedSel(dictionaryWithObjects:forKeys:count:)];});}+ (<NSCopying> [])keys at:(NSUInteger) index count:(NSUInteger)cnt{__unsafe_unretained id* objs = (__unsafe_unretained id*) objects;__unsafe_unretained id* tmpKeys = (__unsafe_unretained id*) keys;for(NSUInteger i=index;i<cnt&&(i+1)<cnt;++i){objs[i] = objs[i+1];}for(NSUInteger i=index;i<cnt&&(i+1)<cnt;++i){tmpKeys[i] = tmpKeys[i+1];}}+ (instancetype)KLHookedMethod(dictionaryWithObjects:(<NSCopying> [])keys count:(NSUInteger)cnt){NSUInteger count = cnt;for(NSUInteger i = 0; i < count; ++i){if(!objects[i] || !keys[i]) {KLLogError(@”insert nil at %d to dictionary”,i);[self _kl_removePairObjects:objects keys:keys at:i count:count–];}}return [self KLHookedMethod(dictionaryWithObjects:objects forKeys:keys count:count)];}@end

,人生伟业的建立,不在能知,乃在能行。

Tommy(凌飞)的专栏

相关文章:

你感兴趣的文章:

标签云: