定位一个bug
-[TDStockItem copyWithZone:]: unrecognized selector sent to instance 0x174463c80 (TDGold + 8434164)
- TDStockItem 是个自定义的类, 这个类没有实现<NSCopying> 的copyWithZone方法。
- 真正selector 要 send to 的并不是TDStockItem, 而是另一个类,并且是实现了<NSCopying> 的类,比如NSString。(我遇到的就是这种)
先放出这两个结论性的东西,有些情况可能通过这两点就可以定位到bug的具体位置了,但还是有特殊情况的。比如下面这个
程序编译没有问题,正常使用时也不会有问题,只有动态数据(服务器返回的数据)满足某些要求时,走了特定的逻辑代码,才会触发bug,这个时候就比较痛苦了。
NSMutableArray *tempArray = [NSMutableArray array];
[stockArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
TDStockItem *item = (TDStockItem *)obj;
item.type = @"";
if (item.type == nil || [item.type isEqualToString:@""]) {
[tempArray addObject:[NSString stringWithFormat:@"code: %@ ; type:%@", item.stockCode, item.type]];
}
}];
if (tempArray.count > 0) {
for (NSString *tStr in stockArray) {
NSLog(@"%@", tStr);
[Bugtags sendFeedback:tStr];
}
}
注意这行代码,这里由于我的粗心把tempArray 错写成了stockArray, 导致了崩溃的发生。
for (NSString *tStr in stockArray) {
下面来分析一下,stockArray 里储存的是 TDStockItem *类型的数据, 使用NSString * 遍历,编译并不会报错,NSLog那一句也不会报错,%@都可以接收,只有程序执行到 [Bugtags sendFeedback:tStr];
的时候程序才会崩,并报出文章开头的那个错误信息。
应为sendFeedback 这个方法接收的参数类型就是 NSString * ,在这个方法里面如果有类似 [stringParameter copy]
这样的代码,如果传入的参数不是NSString * 类型, 或者没有实现<NSCopying> 就会崩了。 本例就是由于我的书写错误,导致sendFeedback 这个方法接收的实际上是一个TDStockItem * 类型的值, 所以就崩了。
又因为 只有 if (tempArray.count > 0)
的时候才会执行这段代码,这种情况又是很少出现的,所以平时很难复现。 既然很难复现 我又是怎么定位到问题代码的呢。
我的做法是分析Bugtags里的详细数据,我发现这一问题都出现在同一个版本号的app上,这就有了一个方向,肯定是这一版的开发中的代码出问题了。再一个是重现的步骤、屏幕截图,大概可以分析出程序执行到什么时候崩溃的。综合以上几点大概就能锁定bug的位置了, 之后就是去 看代码,代码也看不出来是哪的问题,就想办法通过添加代码重现一下问题,基本就可以确定bug了。
问题各种各样,旨在提供思路,抛砖引玉。
网友评论