iOS防止数组越界崩溃
一盏灯, 一片昏黄; 一简书, 一杯淡茶。 守着那一份淡定, 品读属于自己的寂寞。 保持淡定, 才能欣赏到最美丽的风景! 保持淡定, 人生从此不再寂寞。
写文章的初衷
有时候项目中总是出现一些无法预知的情况,导致数组越界是程序crash,如果这种意外情况无法避免,那么只能从侧面采取保护措施。一个大的项目多人一起开发,难免会有人忘记在使用数组时忘记采取一些措施防止数组越界崩溃,所以我想着自己写一套防止数组越界的工具类供同事们一起使用,这样一来项目在防数组越界方面就比较统一方便了,我先从网上找答案,我想其他人也肯定遇到过相同的情况,如果有好的解决方案 ,直接采用就可以。
数组越界的几种情况
- 取值:index超出array的索引范围
- 添加:插入的object为nil或者Null =
- 删除:index超出array的索引范围
- 替换:index超出array的索引范围、替换的object为nil或者Null
解决思路
第一种解决思路:利用runtime, 把array中的以上几种情况的方法替换成自己的方法,然后再执行方法的时候加以判断,这个是网上很多文章比较推荐的方案。网络上的资料也比较多,我就不黏贴代码了。相关参考资料:https://www.jianshu.com/p/9f799cf6a40c
优点:需要围绕”高内聚,低耦合”的思想来实现,对原代码入侵越少越好
缺点 :程序有时候卡死,还会crash,找了找原因,发现NSArray和 NSMutableArray的那几个方法,系统自己会调用很多很多次,极大的影响了性能,还有网友遇到了其他的问题:替换了objectAtIndex方法有输入的地方出来了软键盘按手机Home键就Crash了,简直无解。搜集的关于崩溃的相关资料
第二种解决思路:写分类
1.NSArray添加的分类方法:
#import "NSArray+beyond.h"
@implementation NSArray (beyond)
- (id)objectAtIndexCheck:(NSUInteger)index {
if (index < self.count) {
return [self objectAtIndex:index];
}
return nil;
}
@end
2.NSMutableArray添加的分类方法:
#import "NSMutableArray+beyond.h"
@implementation NSMutableArray (beyond)
- (id)objectAtIndexCheck:(NSUInteger)index {
if (index < self.count) {
return [self objectAtIndex:index];
}
NSLog(@"%@", [NSThread callStackSymbols]);
return nil;
}
- (void)addObjectCheck:(id)anObject {
if (anObject != nil && [anObject isKindOfClass:[NSNull class]] == NO) {
[self addObject:anObject];
} else {
NSLog(@"%@", [NSThread callStackSymbols]);
}
}
- (void)insertObjectCheck:(id)anObject atIndex:(NSUInteger)index {
if (index <= self.count && anObject != nil && [anObject isKindOfClass:[NSNull class]] == NO) {
[self insertObject:anObject atIndex:index];
} else {
NSLog(@"%@", [NSThread callStackSymbols]);
}
}
- (void)removeObjectAtIndexCheck:(NSUInteger)index {
if (index < self.count) {
[self removeObjectAtIndex:index];
} else {
NSLog(@"%@", [NSThread callStackSymbols]);
}
}
- (void)replaceObjectAtIndexCheck:(NSUInteger)index withObject:(id)anObject {
if (index < self.count && anObject != nil && [anObject isKindOfClass:[NSNull class]] == NO) {
[self replaceObjectAtIndex:index withObject:anObject];
} else {
NSLog(@"%@", [NSThread callStackSymbols]);
}
}
@end
优点:大家对分类还是比较熟悉的,通俗易懂,不会带来新的问题
缺点:需要改变开发人员的调用习惯,项目中已存在的数组调用的地方,如果需要统一改成调用分类防止数组崩溃的话,工作量比较大。
总结
通过对比两种方案和结合自己的开发经验,我觉得还是用增加分类的方法比较靠谱一点,通俗易懂,更利于保持项目的稳定性,项目中已存在的数组调用的地方只能以后遇到的时候逐一改成调用分类,或者没有出现问题的,暂时统一不需要改动,毕竟保持项目的稳定性是第一位的。
相关参考资料
markdown语法:https://www.jianshu.com/p/ebe52d2d468f#index
第一种解决思路:https://blog.csdn.net/qq_15509071/article/details/87600664
第一种解决思路带来的崩溃:https://blog.csdn.net/qq_15509071/article/details/87600664
第二种解决思路:https://www.jianshu.com/p/b0d3a64e76a2
网友评论