iOS开发-高级汇总iOS大咖说iOS备忘录

iOS防闪退开发指南

2019-07-24  本文已影响120人  Aaron_ZhangKH

AFNetworking开启removesKeysWithNullValues = YES

使用YYModel接收后台接口返回的data

@interface HR_Applicant : MP_BaseModel
@property (nonatomic,copy  ) NSString *applicantId;
@property (nonatomic,copy  ) NSString *name;
@property (nonatomic,strong) HR_Resume *resume;
@end

@interface HR_Resume : MP_BaseModel
@property (nonatomic,copy  ) NSString *birthYear;
@property (nonatomic,copy  ) NSString *imageUrls;
@end
@interface HR_Applicant : MP_BaseModel
@property (nonatomic,copy  ) NSString *applicantId;
@property (nonatomic,copy  ) NSString *name;
@property (nonatomic,strong) NSDictionary *resume;
@end

@implementation HR_Applicant 
- (void)parseResumeData{
    NSDictionary *responseDict = [self responseObject];
    NSDictionary *resume = responseDict[@"resume"];
    self.resume = resume;
}
@end

通过宏定义的写法来判空

原因:宏定义中进行了“类型判断”、“null判断”、“空值判断”,判空会更加严谨

- (void)demo{
    NSString *str = [self getString];
    if (kStringIsEmpty(str)) {
        return;
    }

    NSArray *arr = [self getArray];
    if (kArrayIsEmpty(arr)) {
        return;
    }

    NSDictionary *dict = [self getDict];
    if (kDictIsEmpty(dict)) {
        return;
    }
    //......
}


- (void)demo{
    NSString *str = [self getString];
    if (str.length == 0) {
        return;
    }

    NSArray *arr = [self getArray];
    if (arr.count == 0) {
        return;
    }

    NSDictionary *dict = [self getDict];
    if (dict.allKeys.count == 0) {
        return;
    }
   // ......
}

通过JKCategories对NSDictionary进行取值和赋值

    //赋值
    NSString *str = [self getString];
    BOOL boolValue = [self getBool];
    NSMutableDictionary *dictM = [NSMutableDictionary dictionary];
    [dictM jk_setString:str forKey:@"str"];
    [dictM jk_setBool:boolValue forKey:@"bool"];

    //取值
    NSString *str = [dict jk_stringForKey:@"str"];
    //赋值
    NSString *str = [self getString];
    BOOL boolValue = [self getBool];
    NSDictionary *dict = @{@"str" : str,
                           @"bool" : @(boolValue)};

    //取值
    NSString *str = dict[@"str"];

开启JJException,自动拦截闪退。

通过MethodSwizzle技术,hook掉系统方法,拦截闪退

闪退原因:attempt to delete row 1 from section 0 which only contains 1 rows before the update

上述闪退发生的原因:tableView通过系统方法reloadRowsAtIndexPaths:withRowAnimation:试图刷新一个越界的NSIndexPath。
解决方法:hook掉reloadRowsAtIndexPaths:withRowAnimation:方法,先做判断,再执行。
代码示例:


@implementation UITableView (FixCrash)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Method originalMethod = class_getInstanceMethod(self.class, @selector(reloadRowsAtIndexPaths:withRowAnimation:));
        Method swizzleMethod = class_getInstanceMethod(self.class, @selector(safeReloadRowsAtIndexPaths:withRowAnimation:));
        method_exchangeImplementations(originalMethod, swizzleMethod);
    });
}


- (void)safeReloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation{
    NSUInteger totalSectionCount = self.numberOfSections;
    for (NSIndexPath *indexPath in indexPaths) {
        if (indexPath.section >= totalSectionCount) {
            return;
        }
        NSUInteger totalRowCount = [self numberOfRowsInSection:indexPath.section];
        if (indexPath.row >= totalRowCount) {
            return;
        }
    }
    [self safeReloadRowsAtIndexPaths:indexPaths withRowAnimation:animation];
}


@end

第三方闪退(例如高德地图)

上一篇下一篇

猜你喜欢

热点阅读