iOS调试技巧

iOS 崩溃溯源

2018-07-26  本文已影响1人  wustzhy

1. unrecognized selector 类crash调试

-[__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如下。

 -[__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上;不行就网查。

上一篇下一篇

猜你喜欢

热点阅读