默认的LLDB
虽然强大,但是使用过程中并不是很方便。在这个过程中有两个插件chisel
和LLDB
,他们相当于给LLDB
重新写了个定义。
一、chisel
chisel是facebook
推出的工具。它是对LLDB API
的封装。
1.1 chisel安装
brew update
brew install chisel
安装很简单直接使用homebrew
安装。
更新
brew upgrade chisel
1.2 chisel配置
在.lldbinit
中增加配置:
command script import /usr/local/opt/chisel/libexec/fbchisellldb.py
没有.lldbinit
目录的话则在家目录下创建一个(老版本的文件时fblldb.py
)。
1.3 chisel命令
配置完成重新运行项目就可以在xcode
的lldb
中使用了。可以通过help <command>
查看具体用法。
pviews
Syntax: pviews [--up] [--depth=depth] [--window=window] [--short] [--medium] <aView>
循环打印view
层级,正常情况下等效于调用recursiveDescription
命令
(lldb) po [self.view recursiveDescription]
(lldb) pviews self.view
-
--up/-u
: 以view
为起始位置,向上打印,直到打印到window
层 -
--depth/-d
: 传入int
类型,表示打印的层数,0
表示没有限制 -
pviews
:不带任何参数则打印所有视图。
pvc
Syntax: pvc <aViewController>
循环打印viewController
的层级,不传参数默认当前vc
。
pclass
Syntax: pclass <object>
循环打印class
的继承关系。
(lldb) pclass 0x7fb4b1906330
ViewController
| UIViewController
| | UIResponder
| | | NSObject
presponder
Syntax: presponder <startResponder>
打印响应链。
(lldb) presponder 0x7fb4aec08160
<UIButton: 0x7fb4aec08160; frame = (172 338; 46 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x60000027e800>>
| <UIView: 0x7fb4b1907ac0; frame = (0 0; 390 844); autoresize = W+H; layer = <CALayer: 0x600000238ee0>>
| | <ViewController: 0x7fb4b1906330>
| | | <UIDropShadowView: 0x7fb4aef08040; frame = (0 0; 390 844); autoresize = W+H; layer = <CALayer: 0x60000022bbe0>>
| | | | <UITransitionView: 0x7fb4b1806300; frame = (0 0; 390 844); autoresize = W+H; layer = <CALayer: 0x60000024dc60>>
| | | | | <UIWindow: 0x7fb4b19075d0; frame = (0 0; 390 844); gestureRecognizers = <NSArray: 0x600000c25920>; layer = <UIWindowLayer: 0x600000238140>>
| | | | | | <UIWindowScene: 0x7fb4aef04080; scene = <FBSScene: 0x600002c7da00; identifier: sceneID:com.haier.uhome.sybird-default>; persistentIdentifier = 84A1C936-704A-401B-95A0-F2578FB0B9F0; activationState = UISceneActivationStateForegroundActive; settingsCanvas = <UIWindowScene: 0x7fb4aef04080>; windows = (
"<UIWindow: 0x7fb4b19075d0; frame = (0 0; 390 844); gestureRecognizers = <NSArray: 0x600000c25920>; layer = <UIWindowLayer: 0x600000238140>>"
)>
| | | | | | | <UIApplication: 0x7fb4aee04970>
| | | | | | | | <AppDelegate: 0x60000006c270>
pmethods
Syntax: pmethods [--address] [--instance] [--class] [--name] <instance or class>
打印当前对象都有哪些方法。
(lldb) pmethods 0x7fb4b1906330
Class Methods:
No methods were found
Instance Methods:
- (void)test2:(bool)arg0
- (void)click1:(id)arg0
- (void)click2:(id)arg0
- (void)click3:(id)arg0
- (void).cxx_destruct
- (id)items
- (void)touchesBegan:(id)arg0 withEvent:(id)arg1
- (void)viewDidLoad
- (void)setItems:(id)arg0
pinternals
Syntax: pinternals [--apple] <object>
打印成员属性
(lldb) pinternals 0x7fb4b1906330
(ViewController) $78 = {
UIViewController = {
UIResponder = {
NSObject = {
isa = ViewController
}
}
}
_items = 0x0000600000c21380 @"3 elements"
}
fvc
Syntax: fvc [--name=classNameRegex] [--view=view]
查找viewController
。
-
--name/-n
:string
类型参数,根据viewController
的Class
名字查找viewController
-
--view/-v
:UIView
类型参数,根据viewController
拥有的view
查找viewController
(lldb) fvc -v 0x7fb4aed06610
Found the owning view controller.
<ViewController: 0x7fb4b1906330>
fv
Syntax: fv <classNameRegex>
根据view
的名字查找view
(lldb) fv UIButton
0x7fb4b190a570 UIButton
0x7fb4aed06610 UIButtonLabel
0x7fb4aec07e80 UIButton
0x7fb4b1905400 UIButtonLabel
0x7fb4aec08160 UIButton
0x7fb4aee07e40 UIButtonLabel
flicker
将view
闪烁一下,以便于查找view
的位置
Syntax: flicker <viewOrLayer>
-
<viewOrLayer>
:需要闪烁的view
或者layer
。
taplog
将点击的view
打印出来。
Syntax: taplog
vs
在view
层级中搜索view
,并显示出来
Syntax: vs <view>
相比
fv
,vs
主要用于显示view
在屏幕上的位置
(lldb) vs 0x7fa50070dfb0
Use the following and (q) to quit.
(w) move to superview
(s) move to first subview
(a) move to previous sibling
(d) move to next sibling
(p) print the hierarchy
<UIButton: 0x7fa50070dfb0; frame = (172 338; 46 30); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x6000036a2160>>
-
w
: 移动到superview
-
s
: 移动到第一个subview
-
a
: 移动到前面的同级view
-
d
: 移动到后面的同级view
-
p
: 打印出层级 -
q
: 退出
可以配合以上命令在层级中查找view
。
更多命令参考官方文档。
二、Derekselander/LLDB
2.1 LLDB安装
下载整个工程,将整个工程拷贝到/opt
目录中。
image.png
2.2 LLDB配置
在.lldbinit
中增加配置:
command script import /opt/LLDB/lldb_commands/dslldb.py
注意路径为自己拷贝的路径地址。
2.3 LLDB命令
search
查找类及其子类。
Syntax: search
-
-e
:忽略子类。 -
-c
:查找对应tag
的类和子类。
search UIView -c "(int)[obj tag]==5"
(lldb) search UIView
<UIView: 0x7ff307e05800; frame = (172 338; 46 30); alpha = 0.4; tag = 140681785939936; layer = <CALayer: 0x600000065200>>
<UIView: 0x7ff307c07c70; frame = (291 338; 46 30); alpha = 0.4; tag = 140681785939200; layer = <CALayer: 0x60000000ad80>>
<UIView: 0x7ff307c06390; frame = (291 338; 46 30); alpha = 0.4; tag = 140681785939200; layer = <CALayer: 0x60000000ada0>>
<UIButtonLabel: 0x7ff30a0059a0; frame = (0 6; 46 18); text = 'Button'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60000230d450>>
methods
查找对象对应的方法
methods 0x7ff30a009e70
(lldb) methods 0x7ff30a504da0
<ViewController: 0x7ff30a504da0>:
in ViewController:
Properties:
@property (retain, nonatomic) NSMutableArray* items; (@synthesize items = _items;)
Instance Methods:
- (void) test2:(BOOL)arg1; (0x1035ebbf0)
- (void) click1:(id)arg1; (0x1035ebb30)
- (void) click2:(id)arg1; (0x1035ebb70)
- (void) click3:(id)arg1; (0x1035ebbb0)
- (void) .cxx_destruct; (0x1035ebc80)
- (id) items; (0x1035ebc20)
- (void) touchesBegan:(id)arg1 withEvent:(id)arg2; (0x1035ebaa0)
- (void) viewDidLoad; (0x1035eb830)
- (void) setItems:(id)arg1; (0x1035ebc40)
(UIViewController ...)
对应的pmethods
信息:
(lldb) pmethods 0x7ff30a504da0
Class Methods:
No methods were found
Instance Methods:
- (void)test2:(bool)arg0
- (void)click1:(id)arg0
- (void)click2:(id)arg0
- (void)click3:(id)arg0
- (void).cxx_destruct
- (id)items
- (void)touchesBegan:(id)arg0 withEvent:(id)arg1
- (void)viewDidLoad
- (void)setItems:(id)arg0
它与chisel
的pmethods
相比信息更全,带了地址。
sbt
sbt
相比bt
恢复了oc
的符号。
(lldb) sbt
frame #0 : 0x1035ebc0d LLDBTest`-[ViewController test2:] + 29
frame #1 : 0x1035ebaff LLDBTest`-[ViewController touchesBegan:withEvent:] + 95
frame #2 : 0x7fff246ca70f UIKitCore`forwardTouchMethod + 321
frame #3 : 0x7fff246ca5bd UIKitCore`-[UIResponder touchesBegan:withEvent:] + 49
frame #4 : 0x7fff246d95b5 UIKitCore`-[UIWindow _sendTouchesForEvent:] + 622
frame #5 : 0x7fff246db6c7 UIKitCore`-[UIWindow sendEvent:] + 4774
frame #6 : 0x7fff246b5466 UIKitCore`-[UIApplication sendEvent:] + 633
frame #7 : 0x7fff24745f04 UIKitCore`__processEventQueue + 13895
frame #8 : 0x7fff2473c877 UIKitCore`__eventFetcherSourceCallback + 104
frame #9 : 0x7fff2039038a CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
frame #10: 0x7fff20390282 CoreFoundation`__CFRunLoopDoSource0 + 180
frame #11: 0x7fff2038f764 CoreFoundation`__CFRunLoopDoSources0 + 248
frame #12: 0x7fff20389f2f CoreFoundation`__CFRunLoopRun + 878
frame #13: 0x7fff203896d6 CoreFoundation`CFRunLoopRunSpecific + 567
frame #14: 0x7fff2c257db3 GraphicsServices`GSEventRunModal + 139
frame #15: 0x7fff24696cf7 UIKitCore`-[UIApplication _run] + 912
frame #16: 0x7fff2469bba8 UIKitCore`UIApplicationMain + 101
frame #17: 0x1035ec022 LLDBTest`main + 114
frame #18: 0x7fff2025a3e9 libdyld.dylib`start + 1
更多命令和用法直接参考官网的示例。