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]

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 == @"北京",那么设置条件断点(双击”断点“)

Xcode这些lldb、断点调试方法,你常用吗?_第1张图片
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
Xcode这些lldb、断点调试方法,你常用吗?_第2张图片
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命令,pvcpclass...
(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 .
pviews       -- Print the recursion description of .
·
visualize    -- Open a UIImage, CGImageRef, UIView, or CALayer in Preview.app
                  on your Mac.
···
··
·

使用时常用的有: pvc,presponder,pclass,visualize

(1) pvc ,打印各层级控制器

(lldb) pvc
, state: appeared, view:  not in the window
   | , state: appeared, view:  not in the window
   |    | , state: appeared, view:  not in the window
   | , state: disappeared, view:  not in the window
   |    | , state: disappeared, view: (view not loaded)
   | , state: disappeared, view:  not in the window
   |    | , state: disappeared, view: (view not loaded)
   + , state: appeared, view: , presented with: <_UIFullscreenPresentationController 0x7f9456f1a1b0>
   |    | , state: appeared, view: 
   |    |    | , state: appeared, view: 
   |    | , state: disappeared, view:  not in the window
   |    |    | , state: disappeared, view: (view not loaded)
   |    | , state: disappeared, view:  not in the window
   |    |    | , state: disappeared, view: (view not loaded)
   |    | , state: disappeared, view:  not in the window
   |    |    | , state: disappeared, view: (view not loaded)
   |    | , state: disappeared, view:  not in the window
   |    |    | , state: disappeared, view: (view not loaded)

这样,拿到一个新项目可以一键看清VC层级结构, 最后一个appeared状态的, state: appeared 即是当前VC

(2) pclass,打印对象继承层级

(lldb) pclass 0x7f945487f200
SHPViewController
   | RTableViewController
   |    | BaseViewController
   |    |    | UIViewController
   |    |    |    | UIResponder
   |    |    |    |    | NSObject

(3) visualize,提供直观看图

(lldb) po [0x10ddaeaa0 image]
 size {12, 12} orientation 0 scale 2.000000
(lldb) visualize 0x1c42a3f60    //mac的preview会打开该图片

比 Xcode提供的Open With Preview好使,毕竟经常出现光标放在那里,却弹不出来这调试框

Xcode这些lldb、断点调试方法,你常用吗?_第3张图片
image.png

(4) presponder,看响应链

(lldb) presponder self

   | ; layer = >
   |    | 
   |    |    | 

你可能感兴趣的:(Xcode这些lldb、断点调试方法,你常用吗?)