Xcode这些lldb、断点调试方法,你常用吗?
<一>列举我常用的lldb调试
1.想要知道cell的indexPath吗?
通过断点处po cell
得到cell的内存地址(或者通过debug view hierarchy),比如0x7fd66f913600
,然后得到indexPath如下
po [(UITableView *)[0x7fd66f913600 superview] indexPathForCell:(UITableViewCell *)0x7fd66f913600]
当然,可以一步步获取:
1.通过
po [0x7fd66f913600 superview]
得到tableView地址 0x7fd66f918888
2.通过po [0x7fd66f918888 indexPathForCell: 0x7fd66f913600 ]
,有时很奇怪,需要加上类型强转,才能正确得到结果,所以保险可用po [(UITableView *)0x7fd66f918888 indexPathForCell: (UITableViewCell *)0x7fd66f913600 ]
2.获取ViewController,根据当前view
通常通过debug view hierarchy 去看 viewController,挺耗时的,慢卡,所以有时会使用nextResponder
(lldb) po [(UIView *)0x7fd44c439bb0 nextResponder]
<ViewController: 0x7fd44c41b180>
3.获取对象的引用计数
po [0x7fd44c439bb0 valueForKey:@"retainCount"]
另外,通过上面方式,即可实测 重复
addsubview
不会增加引用计数
[self.view addSubview:view1];
[self.view addSubview:view1];
[self.view addSubview:view1];
估计接口内部处理过了,所以- (BOOL)isDescendantOfView:(UIView *)view;
方法不必用来判断一下,返回NO才执行addsubview
,直接addsubview
4.精准定位到满足条件的某个cell
a> 最简单的,通过属性就可以解决的。比如,想在"北京"那个cell中断,即条件为cell.textLabel.text == @"北京"
,那么设置条件断点(双击”断点“)
image.png
b> 最复杂的,满足条件的cell太多,或条件会变(但我所跟定的cell不变),或没有可以直接获取的属性。我是这样处理的:通过debug view hierarchy,print Description of XX , 拿到所看到的那个cell的地址0x7fd8b360c290
,然后 设置条件断点条件:[[NSString stringWithFormat:@"%lx",(long int)self] isEqualToString:@"7fd8b360c290"]
,图片略(同上)
5.监听变量 断点调试
watchpoint set命令用于添加一个watchpoint。只要这个地址中的内容变化了,程序就会中断。
(lldb) watchpoint set variable self->_type
Watchpoint created: Watchpoint 1: addr = 0x131512680 size = 8 state = enabled type = w
watchpoint spec = 'self->_type'
new value: CCMediaTypeVideo
image.png
删除watchpoint
(lldb) watchpoint delete 1
6. 执行表达式
expression
命令的作用是执行一个表达式,并将表达式返回的结果输出
(lldb) e int32_t a = 1; OSAtomicIncrement32(&a);
error: 'OSAtomicIncrement32' has unknown return type; cast the call to its declared return type
根据报错原因 fix后
(lldb) e int32_t a = 5;printf("%d,%d",a,a++); (int32_t)OSAtomicIncrement32(&a);
(int32_t) $6 = 7
5,5(lldb) e int32_t a = 5;printf("%d,%d",a,++a); (int32_t)OSAtomicIncrement32(&a);
(int32_t) $7 = 7
5,6(lldb)
......更多不一一列举咯
LLDB的命令其实还有很多,很多命令我也没玩过。就算玩过的命令,我们也非常容易忘记,下次可能就不记得是怎么用的了。还好LLDB给我们提供了2个查找命令的命令:help & apropos
- help
(lldb) help watchpoint
The following subcommands are supported:
command -- A set of commands for adding, removing and examining bits of
code to be executed when the watchpoint is hit (watchpoint
'commmands').
delete -- Delete the specified watchpoint(s). If no watchpoints are
specified, delete them all.
disable -- Disable the specified watchpoint(s) without removing it/them.
If no watchpoints are specified, disable them all.
enable -- Enable the specified disabled watchpoint(s). If no watchpoints
are specified, enable all of them.
ignore -- Set ignore count on the specified watchpoint(s). If no
watchpoints are specified, set them all.
list -- List all watchpoints at configurable levels of detail.
modify -- Modify the options on a watchpoint or set of watchpoints in
the executable. If no watchpoint is specified, act on the
last created watchpoint. Passing an empty argument clears the
modification.
set -- A set of commands for setting a watchpoint.
- apropos
(lldb) apropos stop-hook
The following built-in commands may relate to 'stop-hook':
_regexp-display -- Add an expression evaluation stop-hook.
_regexp-undisplay -- Remove an expression evaluation stop-hook.
target stop-hook -- A set of commands for operating on debugger
target stop-hooks.
target stop-hook add -- Add a hook to be executed when the target stops.
target stop-hook delete -- Delete a stop-hook.
target stop-hook disable -- Disable a stop-hook.
target stop-hook enable -- Enable a stop-hook.
target stop-hook list -- List all stop-hooks.
时间多的,可以去看👉熟练使用 LLDB,让你调试事半功倍
<二> get到的更厉害的lldb技能
----------------- 自定义lldb命令 by Facebook
- 安装chisel 传送门👉 facebook/chisel
- 确认安装好使不,用help看看xcode控制台有没有
Current user-defined commands
自定义的lldb命令,pvc
、pclass
...
(lldb) help
Debugger commands:
apropos -- List debugger commands related to a word or subject.
breakpoint -- Commands for operating on breakpoints (see 'help b' for
shorthand.)
bugreport -- Commands for creating domain-specific bug reports.
command -- Commands for managing custom LLDB commands.
···
··
·
Current user-defined commands:
alamborder -- Put a border around views with an ambiguous layout
alamunborder -- Removes the border around views with an ambiguous layout
binside -- Set a breakpoint for a relative address within the
framework/library that's currently running. This does the
work of finding the offset for the framework/library and
sliding your address accordingly.
···
··
·
pclass -- Print the inheritance starting from an instance of any class.
·
pvc -- Print the recursion description of <aViewController>.
pviews -- Print the recursion description of <aView>.
·
visualize -- Open a UIImage, CGImageRef, UIView, or CALayer in Preview.app
on your Mac.
···
··
·
使用时常用的有: pvc,presponder,pclass,visualize
(1) pvc ,打印各层级控制器
(lldb) pvc
<BaseTabBarController 0x7f9456006800>, state: appeared, view: <UILayoutContainerView 0x7f9456e07ea0> not in the window
| <BaseNavigationController 0x7f945481e000>, state: appeared, view: <UILayoutContainerView 0x7f94544f51c0> not in the window
| | <HPViewController 0x7f9455053c00>, state: appeared, view: <UIView 0x7f9456c36af0> not in the window
| <BaseNavigationController 0x7f9454809a00>, state: disappeared, view: <UILayoutContainerView 0x7f9454409a10> not in the window
| | <LSTableViewController 0x7f94547eaff0>, state: disappeared, view: (view not loaded)
| <BaseNavigationController 0x7f9456000000>, state: disappeared, view: <UILayoutContainerView 0x7f9456e00b60> not in the window
| | <MTeViewController 0x7f9456e00090>, state: disappeared, view: (view not loaded)
+ <BaseTabBarController 0x7f945581b200>, state: appeared, view: <UILayoutContainerView 0x7f94547f33d0>, presented with: <_UIFullscreenPresentationController 0x7f9456f1a1b0>
| | <BaseNavigationController 0x7f945485be00>, state: appeared, view: <UILayoutContainerView 0x7f9456d698d0>
| | | <SHPViewController 0x7f945487f200>, state: appeared, view: <UIView 0x7f9456c6eb60>
| | <BaseNavigationController 0x7f94560afe00>, state: disappeared, view: <UILayoutContainerView 0x7f94546e1700> not in the window
| | | <CTableViewController 0x7f9456d71090>, state: disappeared, view: (view not loaded)
| | <BaseNavigationController 0x7f9455028a00>, state: disappeared, view: <UILayoutContainerView 0x7f9456c1f3c0> not in the window
| | | <LTableViewController 0x7f9456c1d800>, state: disappeared, view: (view not loaded)
| | <BaseNavigationController 0x7f94560a2a00>, state: disappeared, view: <UILayoutContainerView 0x7f9456e3e7f0> not in the window
| | | <VTableViewController 0x7f94547f56c0>, state: disappeared, view: (view not loaded)
| | <BaseNavigationController 0x7f94548be800>, state: disappeared, view: <UILayoutContainerView 0x7f9456d75940> not in the window
| | | <MTableViewController 0x7f9456d76170>, state: disappeared, view: (view not loaded)
这样,拿到一个新项目可以一键看清VC层级结构, 最后一个appeared状态的
<SHPViewController 0x7f945487f200>, state: appeared
即是当前VC
(2) pclass,打印对象继承层级
(lldb) pclass 0x7f945487f200
SHPViewController
| RTableViewController
| | BaseViewController
| | | UIViewController
| | | | UIResponder
| | | | | NSObject
(3) visualize,提供直观看图
(lldb) po [0x10ddaeaa0 image]
<UIImage: 0x1c42a3f60> size {12, 12} orientation 0 scale 2.000000
(lldb) visualize 0x1c42a3f60 //mac的preview会打开该图片
比 Xcode提供的Open With Preview
好使,毕竟经常出现光标放在那里,却弹不出来这调试框
image.png
(4) presponder,看响应链
(lldb) presponder self
<ViewController: 0x7fd8b3404170>
| <UIWindow: 0x7fd8b370c2c0; frame = (0 0; 375 667); autoresize = W+H; gestureRecognizers = <NSArray: 0x61000005bc30>; layer = <UIWindowLayer: 0x61000003d6e0>>
| | <UIApplication: 0x7fd8b3601280>
| | | <AppDelegate: 0x61800003a940>