Xcode5 如何调试 快速定位出错行

夜星辰
  • 51

、、、objectivec
2014-07-21 18:02:38.259 Sections[2962:70b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'must pass a class of kind UITableViewCell'
*** First throw call stack:
(
0 CoreFoundation 0x017375e4 exceptionPreprocess + 180
1 libobjc.A.dylib 0x014ba8b6 objc_exception_throw + 44
2 CoreFoundation 0x017373bb +[NSException raise:format:] + 139
3 UIKit 0x00314e08 -[UITableView registerClass:forCellReuseIdentifier:] + 247
4 Sections 0x000030eb -[BIDViewController searchDisplayController:didLoadSearchResultsTableView:] + 171
5 UIKit 0x005cc0b4 -[UISearchDisplayController searchResultsTableView] + 446
6 UIKit 0x005cd5f4 -[UISearchDisplayController _containerView] + 1031
7 UIKit 0x005c7563 -[UISearchDisplayController setActive:animated:] + 9462
8 UIKit 0x005cad4f -[UISearchDisplayController searchBarTextDidBeginEditing:] + 298
9 UIKit 0x004f52c9 -[UISearchBar(UISearchBarStatic) _searchFieldBeginEditing] + 113
10 libobjc.A.dylib 0x014cc81f -[NSObject performSelector:withObject:] + 70
11 UIKit 0x0022ec8c -[UIApplication sendAction:to:from:forEvent:] + 108
12 UIKit 0x0022ec18 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
13 UIKit 0x003266d9 -[UIControl sendAction:to:forEvent:] + 66
14 UIKit 0x00326a9c -[UIControl _sendActionsForEvents:withEvent:] + 577
15 UIKit 0x0091254e -[UITextField willAttachFieldEditor:] + 685
16 UIKit 0x0032c4d5 -[UIFieldEditor becomeFieldEditorForView:] + 927
17 UIKit 0x00909643 -[UITextField _becomeFirstResponder] + 160
18 UIKit 0x004f841a -[UISearchBarTextField _becomeFirstResponder] + 98
19 UIKit 0x00386585 -[UIResponder becomeFirstResponder] + 400
20 UIKit 0x00289d0b -[UIView(Hierarchy) becomeFirstResponder] + 114
21 UIKit 0x009090e3 -[UITextField becomeFirstResponder] + 51
22 UIKit 0x005ae651 -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) setFirstResponderIfNecessary] + 135
23 UIKit 0x005b0ba2 -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) oneFingerTap:] + 2640
24 UIKit 0x005a4f8c _UIGestureRecognizerSendActions + 230
25 UIKit 0x005a3c00 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 383
26 UIKit 0x005a566d -[UIGestureRecognizer _delayedUpdateGesture] + 60
27 UIKit 0x005a8bcd ___UIGestureRecognizerUpdate_block_invoke + 57
28 UIKit 0x005a8b4e _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 317
29 UIKit 0x0059f248 _UIGestureRecognizerUpdate + 199
30 UIKit 0x0026bd4a -[UIWindow _sendGesturesForEvent:] + 1291
31 UIKit 0x0026cc6a -[UIWindow sendEvent:] + 1030
32 UIKit 0x00240a36 -[UIApplication sendEvent:] + 242
33 UIKit 0x0022ad9f _UIApplicationHandleEventQueue + 11421
34 CoreFoundation 0x016c08af __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION
+ 15
35 CoreFoundation 0x016c023b __CFRunLoopDoSources0 + 235
36 CoreFoundation 0x016dd30e __CFRunLoopRun + 910
37 CoreFoundation 0x016dcb33 CFRunLoopRunSpecific + 467
38 CoreFoundation 0x016dc94b CFRunLoopRunInMode + 123
39 GraphicsServices 0x036d89d7 GSEventRunModal + 192
40 GraphicsServices 0x036d87fe GSEventRun + 104
41 UIKit 0x0022d94b UIApplicationMain + 1225
42 Sections 0x0000399d main + 141
43 libdyld.dylib 0x01d75701 start + 1
44 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
、、、
如上所示,错误提示,使用的是XCODE5 无法根据错误提示找到出错行,网上有的方法试过不可以。希望知道的同学告知下。谢谢!

回复
阅读 23k
3 个回答
✓ 已被采纳

在 Xcode 的 Breakpoint Navigator 里面添加一个异常断点(Add Exception Breakpoint),然后将断点条件设置成 Exception: Object-C,这样就能在异常抛出之前断下来,你就可以查看当时的调用栈。

注意最好在快要执行到出问题代码的时候才打开这个断点,否则会不断被各种异常干扰。

Ilikewhite
  • 832

你的工程是叫Sections吧?
这就是你的抛异常的地方:
4 Sections 0x000030eb -[BIDViewController searchDisplayController:didLoadSearchResultsTableView:] + 171
BIDViewController类的searchDisplayController方法的代码偏移量171处(差不多就是这个方法的170字符的地方,差不多是第2、3行吧,切记,171不是行号什么的哦)。

关于ios异常分析,在一开始确实是非常头疼的问题,因为它没有直接告诉开发者抛异常的位置,甚至有时候还没有异常堆栈,而即使有异常堆栈也不容易看懂是什么意思,特别还有那个代码偏移量的数字,极具误导性。通常调试的方法比较多,讲完得一晚上。Huan Du回答的异常断点是一种,当然还有日志断言打印查看法、符号断点设置、LLDB调试工具。而我个人还是比较喜欢你题目中发的堆栈分析方法。基本上根据类名、方法名和代码偏移量就能判断出问题了。

关于堆栈报告,简单介绍它里面的内容是什么含义:
比如:
4 Sections 0x000030eb -[BIDViewController searchDisplayController:didLoadSearchResultsTableView:] + 171
一共包括了5部分:分别是4/Sections/0x000030eb/-[BIDVi...ew:]/171
第1部分:堆栈输出序列号,序号越大表示代码越早被调用;
第2部分:调用的方法所属框架(库/工程),例如Sections就是楼主您的工程;
第3部分:调用方法的内存地址,即0x000030eb
第4部分:调用方法名,这个非常重要,即-[BIDViewController searchDisplayController:didLoadSearchResultsTableView:]
第5部分:调用方法编译之后的代码偏移量,这里再次强调不是行号,只是编译后的代码偏移量,但是基本上和字符数差不多,你可以通过一些文本工具,通过统计你的方法的字符偏移量大致的估计出错的行,一般误差在3~5行内。

这里推荐一个小技巧,防止xcode不打印堆栈日志:
在main.m中的main方法上添加@try@catch,就像下面这样:

#import <UIKit/UIKit.h>

#import "AppDelegate.h"

int main(int argc, char* argv[])
{
    @try {
        @autoreleasepool
        {
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }
    @catch (NSException* exception)
    {
        Log(@"Exception=%@\nStack Trace:%@", exception, [exception callStackSymbols]);
    }
}

不过切记发布app前删除try catch包裹哦,亲~~~

DHLL
  • 1
新手上路,请多包涵

[UITableView registerClass:forCellReuseIdentifier:] 这里出错啦!

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏