1:数组NSArray,NSMutableArray添加元素,进行插入数据不能为nil。
2:数组NSArray,NSMutableArray越界检查。
3:字典NSDictionary, NSMutableDictionary添加元素,value不能为nil。
4:集合NSSet,NSmutableSet数据操作,value不能为nil。
- (void)addObject:(ObjectType)object;
- (void)removeObject:(ObjectType)object;
5:NSJSONSerialization 操作对象不能为nil。
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt
error:(NSError **)error;
+ (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;
6:delegate 做 是否响应respondsToSelector判断。
7:block调用进行是否为空判断。
8:NSString , NSMutableString字符串处理越界。
- (NSString *)substringFromIndex:(NSUInteger)from;
- (NSString *)substringToIndex:(NSUInteger)to;
- (NSString *)substringWithRange:(NSRange)range;
9:NSAttributedString字符串处理越界。
- (void)addAttribute:(NSAttributedStringKey)name value:(id)value range:(NSRange)range;
- (void)removeAttribute:(NSAttributedStringKey)name range:(NSRange)range;
10:后台返回数据,从json获取某字段进行字符串或者其他类型方法操作,需对该字段判断是否为字符串类型或者其他类型判断。避免对后台返回NSNull做操作导致崩溃。
我们在公共基础组件增加了NSObject分类(NSObject+TypeConver.h),导致崩溃。对5种常用类型进行检查,大家可以直接使用。
//int类型检查
- (NSInteger)intFromValue:(NSObject *)value
{
if ([value isKindOfClass:[NSNumber class]])
{
return [(NSNumber *)value integerValue];
}
else if ([value isKindOfClass:[NSString class]])
{
return [(NSString *)value integerValue];
}
return 0;
}
//float类型检查
- (CGFloat)floatFromValue:(NSObject *)value
{
if ([value isKindOfClass:[NSNumber class]])
{
return [(NSNumber *)value floatValue];
}
else if ([value isKindOfClass:[NSString class]])
{
return [(NSString *)value floatValue];
}
return 0;
}
//字符串类型检查
- (NSString *)stringFromValue:(NSObject *)value
{
if ([value isKindOfClass:[NSString class]])
{
return (NSString *)value;
}
else if ([value isKindOfClass:[NSNumber class]])
{
return [(NSNumber *)value stringValue];
}
return nil;
}
//bool类型检查
- (BOOL) booleanFromValue:(NSObject *)value
{
if ([value isKindOfClass:[NSNumber class]])
{
return [(NSNumber *)value boolValue];
}
else if ([value isKindOfClass:[NSString class]])
{
if ([self compareString1:(NSString *)value string2:@"true"]) {
return YES;
}
else if ([self compareString1:(NSString *)value string2:@"false"])
{
return NO;
}
else if ([self compareString1:(NSString *)value string2:@"yes"])
{
return YES;
}
else if ([self compareString1:(NSString *)value string2:@"no"])
{
return NO;
}
else {
return [(NSString *)value boolValue];
}
}
return NO;
}
//时间类型检查
- (NSDate *)dateFromValue:(NSObject *)value
{
if ([value isKindOfClass:[NSDate class]]) {
return (NSDate *)value;
}
else if ([value isKindOfClass:[NSNumber class]]) {
return [NSDate dateWithTimeIntervalSince1970:[(NSNumber *)value doubleValue]];
}
else if ([value isKindOfClass:[NSString class]]) {
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setFormatterBehavior:NSDateFormatterBehavior10_4];
[df setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
[df setDateFormat:@"yyyy-MM-dd"];
NSDate *result = [df dateFromString:(NSString *)value];
return result;;
}
return nil;
}
NULL:用于普通类型,例如NSInteger
nil:用于OC对象(除了类这个对象),给nil对象发送消息不会crash
Nil:用于Class类型对象的赋值(类是元类的实例,也是对象)
NSNull:用于OC对象的站位,一般会作为集合中的占位元素,给NSNull对象发送消息会crash的,后台给我们返回的就是NSNull对象
11,KVO addObserver和removeObserver一定要成对出现,对同一keypath多次removeObserver导致崩溃。
12,对沙盒目录操作时,千万确认不要直接对三个根文件夹:Documents、Library、temp直接做删除操作,对文件操作路径拼接做防空判断。
13,延迟执行方法,注意原来执行的方法是否有防护处理需要同步在延迟执行方法里面防护。
- (void)scrollToSafetyIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated {
//增加防止数组越界崩溃
if (self.chatArray.count <= indexPath.row) {
LogI(TAG_MEETING, @"scrollToSafetyIndexPath:self.chatArray.count <= indexPath.row");
return;
}
NSArray *objects = @[indexPath, @(scrollPosition), @(animated)];
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(delayedScrollToRowAtIndexPath:) object:objects];
[self performSelector:@selector(delayedScrollToRowAtIndexPath:) withObject:objects afterDelay:0.005];
}
- (void)delayedScrollToRowAtIndexPath:(NSArray *)objects {
NSIndexPath *indexPath = [objects firstObject];
UITableViewScrollPosition scrollPosition = [objects[1] integerValue];
BOOL animated = [[objects lastObject] boolValue];
//延迟执行方法里面,必须跟着原来执行方法,增加防止数组越界崩溃
if (self.chatArray.count <= indexPath.row) {
LogI(TAG_MEETING, @"delayedScrollToRowAtIndexPath:self.chatArray.count <= indexPath.row");
return;
}
[self.chatTableView scrollToRowAtIndexPath:indexPath atScrollPosition:scrollPosition animated:animated];
}
14,对源文件进行NSFileManager复制,移动,删除操作的时候,需要对源文件判断是否存在,并做相应异常处理。