iOS 崩溃溯源

作者: wustzhy | 来源:发表于2018-07-26 11:12 被阅读1次

    1. unrecognized selector 类crash调试

    • error_1 log

    -[__NSCFNumber length]: unrecognized selector sent to instance
    

    可以增加NSNumber分类方法,定位调用源头

    #import "NSNumber+length.h"
    
    @implementation NSNumber (length)
    
    //- (NSUInteger)length {
    //    return [NSString stringWithFormat:@"%@",self].length;
    //}
    
    @end
    
    

    以上处理,可以知道该number大小(eg: 72),但无法知道谁retain了该number。当然 现实中,如果能根据业务逻辑,推测出该数字会出现在哪,那显然就定位到源头了。但如果 业务逻辑不清楚 无法迅速找出呢?以下方式奏效。

    其实,虽然以上处理避免了崩溃在error_1 但是 没法避免其它异常, 比如label.text若赋值为NSNumber, 在draw时会崩溃在error_2如下。

    • error_2 log

     -[__NSCFNumber hasColorGlyphsInRange:attributes:]: unrecognized selector sent to instance
    
    - 1 如果 hasColorGlyphsInRange:attributes: 是自己写的方法,那就好办了,直接打断点即可溯源
    - 2 如果 hasColorGlyphsInRange:attributes: 是系统方法,咋办 ??

    (1) 知道发生在label.text,其实好办, 如下:

      #import "UILabel+text.h"
      #import <objc/runtime.h>
    
      @implementation UILabel (text)
    
      + (void)load {
          static dispatch_once_t onceToken;
          dispatch_once(&onceToken, ^{
              [self swizzle_SEL:@selector(setText:) withSEL:@selector(swizzled_setText:)];
          });
      }
    
      -(void)swizzled_setText:(NSString *)text {
          
          if (text && ![text isKindOfClass:[NSString class]]) {
              //text = [NSString stringWithFormat:@"%@",text];
          }
          
          [self swizzled_setText:text];
          
      }
    

    以上即可断点 跟出 给text赋值非NSString类型的 调用出

    (2)若不知道发生在label.text, 那咋办?
    根据lldb的bt查看,是什么控件、什么方法,还是能看出来发生在label上;不行就网查。

    相关文章

      网友评论

        本文标题:iOS 崩溃溯源

        本文链接:https://www.haomeiwen.com/subject/kqivmftx.html