iOS 常见崩溃类型

2019-11-07  本文已影响0人  小暖风

1.UIKit Called on Non-Main Thread,非主线程刷新UI

通过runtime的方法替换,替换UIView 的 setNeedsLayout, layoutIfNeeded,layoutSubviews, setNeedsUpdateConstraints。方法,判断当前线程是否为主线程,如果不是,在主线程执行。

例如:

- (void)wt_safe_setNeedsLayout

{

    if(![NSThread isMainThread]){

        dispatch_async(dispatch_get_main_queue(), ^{

            NSAssert(false, @"wt_safe_setNeedsLayout failed");

            [self wt_safe_setNeedsLayout];

        });

    }else{

        [self wt_safe_setNeedsLayout];

    }

}

2.KVO

项目中KVO crash 占比很高, 主要原因为,添加删除不对称导致。

解决方法为,添加Map进行缓存。

所以我在addObserver:forKeyPath:options:context:这个方法里新建了一个字典,用来记录observer和keyPath。

下面需要解决的就是什么时候去调用的问题,我首先想到的是在dealloc时去判断是否添加了KVO的监视,但是当我直接交换了dealloc方法后发现,这个方法调用的太多了,并不适合直接交换,不然整个程序都会卡顿起来,需要找一个时机,于是我又修改为在添加监视的时候去交换dealloc,这次成功了,这样可以减少对不必要的类进行方法交换,同时提高效率。

唯一需要注意的是在ARC的情况下,不能直接@selector(dealloc)来做方法交换,需要变形一下NSSelectorFromString(@"dealloc"),这样才能做方法交换。

3.容器越界(NSArray, NSDictionary,…)

这个问题,就是运用方法替换进行,目前对以下类进行防范,类中可能导致crash 的方法,逐步进行增量扩充。

NSArray

NSMutableArray

NSAttributedString

NSDictionary

NSFileManager

NSIndexPath

NSJSONSerialization

NSMutableAttributedString

NSMutableDictionary

NSMutableSet

NSMutableString

NSSet

NSString

NSURL

4.nil值问题

方法替换,对于Nil不添加,不处理。

5.unrecognized selector crash (这个很多时候是由于class使用错误导致)

方法替换,对于unrecognized selector,执行一个空方法。

[NSObject jr_swizzleMethod:@selector(forwardingTargetForSelector:) withMethod:@selector(WT_safeForwardingTargetForSelector:) error:&error];

    - (id)WT_safeForwardingTargetForSelector:(SEL)aSelector

{

    NSMethodSignature *signature = [self methodSignatureForSelector:aSelector];

    if ([self respondsToSelector:aSelector] || signature) {

        return [self WT_safeForwardingTargetForSelector:aSelector];

    }

    return [WTSafeGuard createFakeForwardTargetObject:self selector:aSelector];

}

上一篇下一篇

猜你喜欢

热点阅读