Xcode 调试方法总结
来源:互联网 发布:远征x431pro3软件下载 编辑:程序博客网 时间:2024/06/05 18:00
前言:编写代码过程中出现错误、异常是不可避免的。通常我们都需要进行大量的调试去寻找、解决问题。这时,熟练掌握调试技巧将很大程度上的提高工作效率。接下来就说说开发过程中Xcode的调试方法。
- 1 . Enable NSZombie Objects (开启僵尸对象)。
这个技巧主要用来追终重复释放的问题。个人认为,ARC推出以来。项目的基本是基于ARC环境。不用开发者主动去调用release去释放对象,所以不用太在意这个方法。这里就不多做介绍了。想了解该方法的同学请 坐飞机 - 2 . 断点调试(全局断点、条件断点)
全局断点:
NSArray *aa = @[@2,@4];NSLog(@"%@",aa[3]);
这两行代码,没有添加全局断点时,运行crash,直接就跳到了mian函数,如下图:
接下来添加全局断点,方法如下图:
添加全局断点的方法
添加之后运行,奔溃后,程序停留在了crash那行代码。
是不是很方便,很省事。哈哈!(ps 不过有的crash,这种方式定位不到)
条件断点:
设置断点触发的条件,方便开发者对特定情况进行调试
如下图:
在for循环中添加一个断点。右击断点选择”Edit BreakPoint”,然后设置断点触发条件。
这个例子当 “i==5”时,断点触发,如下图:
- 3 . Static Analyzer (静态分析)
Static Analyzer主要用于分析内存,避免内存泄漏。主要对以下情况进行分析。
未使用的实例变量、未初始化的实例变量、类型不兼容、无法达到的路径、引用空指针
使用:command + shift +B,如下图就能轻松找到可能内存泄漏的代码,然后我们根据代码环境进行修复就可以了(ps:有的内存泄漏可能检测不出来,还是需要我们在写代码时对内存这块多留点心。)
- 4 . LLDB调试器
这个方法是我今天主推的方法。比较高级,也更加灵活、方便。
随着Xcode5,LLDB调试器已经取代了GDB,成为了Xcode工程中默认的调试器。其实Xcode已经帮我们完成了大部分工作,而且很多东西也可以在Xcode中直接看到。所以这里我们只列举常用的命令。
打印:p,print的缩写:该命令如果打印的是简单类型则会列出简单类型的的类型和值,如果是对象会打印出对象的地址。
po,print Object 的缩写,用于输出OC对象
如下如,当运行到断点处时,控制台就会出现LLDB的调试命令行。我们只需在这里进行调试。
expr:expression的缩写,可以在调试时动态执行指定表达式,并将结果打印出来。常用于在调试过程中修改变量的值。
如上图,你在控制台输入
expr a=2
你就能看到
(NSInteger) $11 = 2
这是a的值就被动态改成了2
除此之外,还可以使用这个命令生成一个新的对象,如:
expr int
b=0p b 这条命令用于输出新申明对象的值(注意要加$)
image: image命令可用于寻址,有多个组合命令,在控制台输入help image可查看image的用法。比较实用的用法是用于寻找栈地址对应的代码位置,下面我们来举个例子:
NSArray *array = @[@1,@2];NSLog(@"%@",array[2]);
这段代码很明显会crash,运行之后抛出下面的异常
2016-03-23 22:26:11.014 Test[3631:136626] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1]'*** First throw call stack:( 0 CoreFoundation 0x0000000104f28f45 __exceptionPreprocess + 165 1 libobjc.A.dylib 0x00000001049a2deb objc_exception_throw + 48 2 CoreFoundation 0x0000000104e17b14 -[__NSArrayI objectAtIndex:] + 164 3 Test 0x00000001044a5829 -[ViewController viewDidLoad] + 265 4 UIKit 0x0000000105467cc4 -[UIViewController loadViewIfRequired] + 1198 5 UIKit 0x0000000105468013 -[UIViewController view] + 27 6 UIKit 0x000000010534151c -[UIWindow addRootViewControllerViewIfPossible] + 61 7 UIKit 0x0000000105341c05 -[UIWindow _setHidden:forced:] + 282 8 UIKit 0x00000001053534a5 -[UIWindow makeKeyAndVisible] + 42 9 UIKit 0x00000001052cd396 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4131 10 UIKit 0x00000001052d39c3 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1750 11 UIKit 0x00000001052d0ba3 -[UIApplication workspaceDidEndTransaction:] + 188 12 FrontBoardServices 0x0000000107c83784 -[FBSSerialQueue _performNext] + 192 13 FrontBoardServices 0x0000000107c83af2 -[FBSSerialQueue _performNextFromRunLoopSource] + 45 14 CoreFoundation 0x0000000104e55011 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 15 CoreFoundation 0x0000000104e4af3c __CFRunLoopDoSources0 + 556 16 CoreFoundation 0x0000000104e4a3f3 __CFRunLoopRun + 867 17 CoreFoundation 0x0000000104e49e08 CFRunLoopRunSpecific + 488 18 UIKit 0x00000001052d04f5 -[UIApplication _run] + 402 19 UIKit 0x00000001052d530d UIApplicationMain + 171 20 Test 0x00000001044a5baf main + 111 21 libdyld.dylib 0x000000010764c92d start + 1 22 ??? 0x0000000000000001 0x0 + 1)libc++abi.dylib: terminating with uncaught exception of type NSException
现在我怀疑出错的地址是0x00000001044a5829(可根据执行文件名或最小的栈地址判断)为进一步精确定位我们可输入以下命令:
image lookup –address 0x00000001044a5829
命令执行后返回结果如下:
Address: Test[0x0000000100001829] (Test.__TEXT.__text + 265)Summary: Test`-[ViewController viewDidLoad] + 265 at ViewController.m:21
由此,我们可以看出出错的地方是ViewController.m文件的第21行。
我们还可以使用image lookup命令查看具体的类,如下:
(lldb) image lookup --type UIViewBest match found in /Users/jamalping/Library/Developer/Xcode/DerivedData/Test-gviuudbzlyhssmanjxpwhchdbscz/Build/Products/Debug-iphonesimulator/Test.app/Test:id = {0x00001e8d}, name = "UIView", byte-size = 8, decl = UIView.h:144, clang_type = "@interface UIView : UIResponder@property ( getter = isUserInteractionEnabled,setter = setUserInteractionEnabled:,assign,readwrite,nonatomic ) BOOL userInteractionEnabled;@property ( getter = tag,setter = setTag:,assign,readwrite,nonatomic ) NSInteger tag;@property ( readonly,getter = layer,setter = <null selector>,nonatomic ) CALayer * layer;@property ( readonly,getter = isFocused,setter = <null selector>,nonatomic ) BOOL focused;@property ( getter = semanticContentAttribute,setter = setSemanticContentAttribute:,assign,readwrite,nonatomic ) UISemanticContentAttribute semanticContentAttribute;@end"
call
call:即调用,如我们在viewDidLoad: 设置一个断点,在程序中断的时候输入call self.view.backgroudColor = [UIColo redColor]继续运行程序,view就变成红色了,在调试的时候灵活运用call命令可以达到事半功倍的效果。
参考:
objc.io#19#与调试器共舞 - LLDB 的华尔兹
浅谈LLDB调试器
Getting interactive with the debugger
- Xcode 调试方法总结
- Xcode 调试方法总结
- Xcode调试方法总结
- Xcode调试总结
- XCode iOS调试总结
- Xcode调试打印方法
- Xcode调试打印方法
- XCode调试方法
- XCODE常用调试方法
- Xcode调试方法
- Xcode 调试FrameWork方法
- Xcode开发调试技巧总结
- Xcode开发调试技巧总结
- 【Xcode使用技巧】Xcode调试方法
- Xcode常用方法总结
- xcode静态库调试方法
- Xcode 调试之方法大全
- xcode 11db 调试台调试方法
- 第四周第二项目——玩乐了(计算sin x的值)
- 关于iOS spritekit学习
- static变量详解
- Codeforces 638C Road Improvement 【DFS】
- 谷歌
- Xcode 调试方法总结
- php ci框架 页面缓存和数据库缓存
- ZJOI2016一试 酱油记
- jenkins+git(分支和master合并)
- PHP发送POST请求的三种方式
- 数据的大端小端表示法
- extjs 表格单元格 垂直居中对齐
- 20160324servlet学习笔记HttpServletRequest对象中文乱码解决方法
- 3月24号