brew update brew install chisel
安装完成按照安装日志上的提示,在 ~/.lldbinit
文件中添加一行,没有则新建。 提示类似如下:
==> Caveats Add the following line to ~/.lldbinit to load chisel when Xcode launches: command script import /usr/local/opt/chisel/libexec/fblldb.py
做好上面的步骤,然后重启 Xcode 就可以尝试下了。
LLDB
与 chisel 都是用 Python 写的,其安装需要手动下载仓库,然后将仓库中 dslldb.py 文件的路径用与上述同样的方式添加到 .lldbinit
中。
扩展
pviews
打印当前层级结构。
(lldb) pviews view <TestView: 0x18df8070; baseClass = UIControl; frame = (144 9; 126 167); layer = <CALayer: 0x18df8150>> | <UIView: 0x18df81d0; frame = (0 0; 126 126); userInteractionEnabled = NO; layer = <CALayer: 0x18df8240>> | <UIImageView: 0x18df8330; frame = (0 0; 126 126); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x18df83b0>> | <UILabel: 0x18df8460; frame = (0 135; 126 14); text = 'haha'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x18df7fb0>> | | <_UILabelContentLayer: 0x131a3d50> (layer) | <UILabel: 0x18df8670; frame = (0 155; 126 12); text = 'hahaha'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x18df8730>> | | <_UILabelContentLayer: 0x131bea10> (layer) | <UIImageView: 0x18df88d0; frame = (0 9; 28 27); hidden = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x18df8ba0>>
pvc
递归打印 viewController 层级,利用它我们可以对 viewController 的结构一目了然。
(lldb) pvc <TabBarController: 0x13772fd0; view = <UILayoutContainerView; 0x151b3a30>; frame = (0, 0; 414, 736)> | <UINavigationController: 0x1602b800; view = <UILayoutContainerView; 0x1b00aca0>; frame = (0, 0; 414, 736)> | | <FirstViewController: 0x16029c00; view = <UIView; 0x1b01e1c0>; frame = (0, 0; 414, 736)> | <UINavigationController: 0x138c5200; view = <UILayoutContainerView; 0x1316a080>; frame = (0, 0; 414, 736)> | | <SecondViewController: 0x16030400; view = <UIView; 0x2094b370>; frame = (0, 0; 414, 736)> | | | <SecondChildViewController: 0x15af6000; view = <UIView; 0x18d4e650>; frame = (0, 64; 414, 628)> | <UINavigationController: 0x1383ca00; view = <UILayoutContainerView; 0x13180070>; frame = (0, 0; 414, 736)> | | <ThirdViewController: 0x138ddc00; view = <UIView; 0x18df6650>; frame = (0, 0; 414, 736)> | | | <ThirdChild1ViewController: 0x1393fe00; view = <UIView; 0x131ec000>; frame = (0, 0; 414, 672)> | | | <ThirdChild2ViewController: 0x138dce00; view = <UIView; 0x204075a0>; frame = (414, 0; 414, 672)> | | | <ThirdChild3ViewController: 0x138a8e00; view = <UIView; 0x20426250>; frame = (828, 0; 414, 672)> | <UINavigationController: 0x160eca00; view = <UILayoutContainerView; 0x152f7d90>; frame = (0, 0; 414, 736)> | | <FourViewController: 0x13157cc0; view not loaded>
visualize
使用 Mac 的预览打开一个 UIImage,CGImageRef,UIView 或 CALayer。
(lldb) visualize imageView
fv & fvc
fv
和 fvc
这两个命令是用来通过类名搜索当前内存中存在的 view 和 viewController 实例的命令,支持正则搜索。
(lldb) fv scrollView 0x18d3b8c0 UIScrollView 0x137d0c50 UIScrollView 0x131b1580 UIScrollView 0x131b2070 UIScrollView (lldb) fvc Home 0x1393fe00 HomeFeedsViewController 0x138a8e00 HomeFeedsViewController (lldb)
show & hide
这两个命令用来显示和隐藏一个指定的 UIView。
mask/umask border/unborder
这两组命令用来标识一个 view 或 layer 的位置时用,mask 用来在 view 上覆盖一个半透明的矩形,border 可以给 view 添加边框。
caflush
这个命令会重新渲染,即可以重新绘制界面,相当于执行了 [CATransaction flush]
方法,要注意如果在动画过程中执行这个命令,就直接渲染出动画结束的效果。
当你想在调试界面颜色、坐标之类的时候,可以直接在控制台修改属性,然后 caflush
就可以看到效果啦,是不是要比改代码,然后重新 build 省事多了呢。
(lldb) p view (long) $122 = 140718754142192 (lldb) e (void)[$122 setBackgroundColor:[UIColor greenColor]] (lldb) caflush
自定义插件
比如设计一个打印 keyWindow 的 windowLevel 的命令:
创建 python 脚本文件 /magical/commands/example.py
:
#!/usr/bin/python # Example file with custom commands, located at /magical/commands/example.py import lldb import fblldbbase as fb def lldbcommands(): return [ PrintKeyWindowLevel() ] class PrintKeyWindowLevel(fb.FBCommand): def name(self): return 'pkeywinlevel' def description(self): return 'An incredibly contrived command that prints the window level of the key window.' def run(self, arguments, options): # It's a good habit to explicitly cast the type of all return # values and arguments. LLDB can't always find them on its own. lldb.debugger.HandleCommand('p (CGFloat)[(id)[(id)[UIApplication sharedApplication] keyWindow] windowLevel]')
其中定义了 PrintKeyWindowLevel
的类,需要实现 name
description
run
方法来分别告诉名称、描述、和执行实体。
创建好脚本后,然后在前面安装时创建的 ~/.lldbinit
文件中添加一行:
script fblldb.loadCommandsInDirectory('/magical/commands/')
然后重启 Xcode 之后就可以使用自定义的命令啦。
技巧
taplog + flicker + show/hide
- taplog 点击控件,打印控件地址、大小和透明度等。
- flicker 执行
地址
命令,控件会闪烁。 - show/hide 执行
地址
命令,控制显示或隐藏。
vs 动态调试
执行 vs
后进入动态调试阶段,会出现五个命令。
(lldb) vs 0x728123771817 Use the following and (q) to quit.
- w:移动到父视图。
- s:移动到第一个子视图。
- a:移动到上一个兄弟视图。
- d:移动到下一个兄弟视图。
- p:打印视图层级结构。