iOS常见容易出错问题checklist

1:数组NSArrayNSMutableArray添加元素,进行插入数据不能为nil。

2:数组NSArrayNSMutableArray越界检查。

3:字典NSDictionary NSMutableDictionary添加元素,value不能为nil。

4:集合NSSetNSmutableSet数据操作,value不能为nil。

- (void)addObject:(ObjectType)object;
- (void)removeObject:(ObjectType)object;

5NSJSONSerialization 操作对象不能为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 addObserverremoveObserver一定要成对出现对同一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复制,移动,删除操作的时候,需要对源文件判断是否存在,并做相应异常处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值