IOS 防止崩溃 Crash 组件

直接上干货 IOS 防止Crash 组件

导致crash 原因,网上一大堆,不废话介绍。此处省略一万字

当前为何的项目 排行高的Crash项


  1. UIKit Called on Non-Main Thread
  2. KVO
  3. 容器越界(NSArray, NSDictionary,…)
  4. unrecognized selector crash (这个很多时候是由于class使用错误导致)

针对以上crash, 进行防止崩溃处理。以下一项项说。


UIKit Called on Non-Main Thread

替换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];
    }
}

- (void)wt_safe_layoutIfNeeded
{
    if(![NSThread isMainThread]){
        dispatch_async(dispatch_get_main_queue(), ^{
            NSAssert(false, @"wt_safe_layoutIfNeeded failed");
            [self wt_safe_layoutIfNeeded];
        });
    }else{
        [self wt_safe_layoutIfNeeded];
    }
}

- (void)wt_safe_layoutSubviews
{
    if(![NSThread isMainThread]){
        dispatch_async(dispatch_get_main_queue(), ^{
            NSAssert(false, @"wt_safe_layoutSubviews failed");
            [self wt_safe_layoutSubviews];
        });
    }else{
        [self wt_safe_layoutSubviews];
    }
}

- (void)wt_safe_setNeedsUpdateConstraints
{
    if(![NSThread isMainThread]){
        dispatch_async(dispatch_get_main_queue(), ^{
            NSAssert(false, @"wt_safe_setNeedsUpdateConstraints failed");
            [self wt_safe_setNeedsUpdateConstraints];
        });
    }else{
        [self wt_safe_setNeedsUpdateConstraints];
    }
}

KVO Crash

项目中KVO crash 占比很高, 主要原因为,添加删除不对称导致。
解决方法为,添加Map进行缓存。具体大家看代码,有问题留言。

容器越界

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

  • NSArray
  • NSMutableArray
  • NSAttributedString
  • NSDictionary
  • NSFileManager
  • NSIndexPath
  • NSJSONSerialization
  • NSMutableAttributedString
  • NSMutableDictionary
  • NSMutableSet
  • NSMutableString
  • NSSet
  • NSString
  • NSURL

unrecognized selector crash

这个就比较简单了,直接上代码:

    [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];
}

你可能感兴趣的:(个人总结)