之前写的代码用到多数组的情况,budly上均显示了崩溃信息,其实原因只有一个,取index的时候index不在,为什么会出现这样的问题,即使index作出了判断,也会存在问题奔溃的问题。为什么会出现此类问题呢,在我看来,数组用起来还存在一定的弊端问题。回到崩溃的原因问题,具体崩溃原因是如果说一个线程正在改变这个数组,另外开辟一个线程用相同的index来改变这个数组,这个index访问的时候数组做出了改变,接下来就发生崩溃情况。总结以上问题,今后如何避免此类问题再次出现,首先对其数组的下标进行判断,保证是一个合理的下标范围,接下来可以有以下方法解决:
解决办法一:可以对数组操作时进行加锁操作加锁类型有很多中,我用了pthread_mutex_lock,用起来很简单:
1.声明一个互斥锁
pthread_mutex_t _lock;//初始化pthread_mutex_init(&_lock,NULL);
2.上锁 解锁
//上锁pthread_mutex_lock(&_lock)//这里加入可能产生死锁的操作 比如像文件写入 读取之类//解锁 pthread_mutex_unlock(&_lock)
2.释放锁
pthread_mutex_destroy(&_lock)
解决方法二:由于是两个线程同时对数组进行的操作,也可以开辟一个线程来对数组进行操作
解决方法三:利用runtime的黑魔法功能,通过替换父类方法来避免崩溃的发生
+ (void)load{ //只执行一次这个方法
staticdispatch_once_tonceToken;
dispatch_once(&onceToken, ^{ //替换 objectAtIndex
NSString*tmpStr =@"objectAtIndex:";
NSString *tmpFirstStr = @"safe_ZeroObjectAtIndex:";
NSString*tmpThreeStr =@"safe_objectAtIndex:";
NSString *tmpSecondStr = @"safe_singleObjectAtIndex:";
// 替换 objectAtIndexedSubscript
NSString*tmpSubscriptStr =@"objectAtIndexedSubscript:";
NSString*tmpSecondSubscriptStr =@"safe_objectAtIndexedSubscript:";
[NSObject exchangeInstanceMethodWithSelfClass:NSClassFromString(@"__NSArray0")
originalSelector:NSSelectorFromString(tmpStr) swizzledSelector:NSSelectorFromString(tmpFirstStr)];
[NSObject exchangeInstanceMethodWithSelfClass:NSClassFromString(@"__NSSingleObjectArrayI")
originalSelector:NSSelectorFromString(tmpStr) swizzledSelector:NSSelectorFromString(tmpSecondStr)];
[NSObject exchangeInstanceMethodWithSelfClass:NSClassFromString(@"__NSArrayI")
originalSelector:NSSelectorFromString(tmpStr) swizzledSelector:NSSelectorFromString(tmpThreeStr)];
[NSObject exchangeInstanceMethodWithSelfClass:NSClassFromString(@"__NSArrayI")
originalSelector:NSSelectorFromString(tmpSubscriptStr) swizzledSelector:NSSelectorFromString(tmpSecondSubscriptStr)];
});
}
#pragma mark --- implement method
/** 取出NSArray 第index个 值 对应 __NSArrayI
@param index 索引 index
@return 返回值*/
- (id)safe_objectAtIndex:(NSUInteger)index {
if(index >=self.count){
returnnil;
}
return [self safe_objectAtIndex:index];
}
/**取出NSArray 第index个 值 对应 __NSSingleObjectArrayI
@param index 索引 index
@return 返回值*/
- (id)safe_singleObjectAtIndex:(NSUInteger)index {
if(index >=self.count){
returnnil;
}
return [self safe_singleObjectAtIndex:index];
}
/**取出NSArray 第index个 值 对应 __NSArray0
@param index 索引 index
@return 返回值*/
- (id)safe_ZeroObjectAtIndex:(NSUInteger)index {
if(index >=self.count){
returnnil;
}
return [self safe_ZeroObjectAtIndex:index];
}
/** 取出NSArray 第index个 值 对应 __NSArrayI
@param idx 索引 idx
@return 返回值*/
- (id)safe_objectAtIndexedSubscript:(NSUInteger)idx {
if(idx >=self.count){
returnnil;
}
return [self safe_objectAtIndexedSubscript:idx];
}