p & po
p
和po
實際都是expression
命令,p
是e --
(e
就是expression
的簡寫)的別名,po
是e -o --
的簡寫速妖。
p
用于執(zhí)行一段表達式虱颗,如p button.backgroundColor = [UIColor blueColor];
用在下面的情況沥匈,原本是紅色的按鈕,會變成藍色
UIButton *button = [[UIButton alloc] initWithFrame:(CGRectMake(30, 100, 100, 30))];
button.backgroundColor = [UIColor redColor];
[self.view addSubview:button];
這個的好處就是可以在運行之后忘渔,我們還可以操控變量的值的來配合調(diào)試高帖。比如有些流程會根據(jù)值不同,走不同的代碼畦粮,用p
命令就可以在運行后繼續(xù)修改調(diào)試散址。
po
用來輸出一個指針指向的對象的值。
(lldb) p button
(UIButton *) $1 = 0x00007fb39c50c1f0
(lldb) po button
<UIButton: 0x7fb39c50c1f0; frame = (30 100; 100 30); opaque = NO; layer = <CALayer: 0x608000031a60>>
比如對于一個按鈕宣赔,使用p
命令预麸,輸出的是指針的數(shù)據(jù),也就是它執(zhí)行那個內(nèi)存的地址儒将,而我們實際需要的信息在指向的對象里吏祸,用po
就可以直接輸出對象信息。
thread backtrace 或 bt
可以用來顯示當(dāng)前的方法調(diào)用棧信息钩蚊。雖然在Xcode里可以查看贡翘,但操作可能沒有在這里來的快捷。
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
* frame #0: 0x0000000107df7562 TestDemo`-[ViewController viewDidLoad](self=0x00007fb39c405600, _cmd="viewDidLoad") at ViewController.m:28
frame #1: 0x0000000108f26cca UIKit`-[UIViewController loadViewIfRequired] + 1235
frame #2: 0x0000000108f2710a UIKit`-[UIViewController view] + 27
frame #3: 0x0000000108def63a UIKit`-[UIWindow addRootViewControllerViewIfPossible] + 65
frame #4: 0x0000000108defd20 UIKit`-[UIWindow _setHidden:forced:] + 294
frame #5: 0x0000000108e02b6e UIKit`-[UIWindow makeKeyAndVisible] + 42
frame #6: 0x0000000108d7c31f UIKit`-[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4346
frame #7: 0x0000000108d82584 UIKit`-[UIApplication _runWithMainScene:transitionContext:completion:] + 1709
frame #8: 0x0000000108d7f793 UIKit`-[UIApplication workspaceDidEndTransaction:] + 182
frame #9: 0x000000010bfc35f6 FrontBoardServices`__FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
frame #10: 0x000000010bfc346d FrontBoardServices`-[FBSSerialQueue _performNext] + 186
frame #11: 0x000000010bfc37f6 FrontBoardServices`-[FBSSerialQueue _performNextFromRunLoopSource] + 45
frame #12: 0x0000000108906c01 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
frame #13: 0x00000001088ec0cf CoreFoundation`__CFRunLoopDoSources0 + 527
frame #14: 0x00000001088eb5ff CoreFoundation`__CFRunLoopRun + 911
frame #15: 0x00000001088eb016 CoreFoundation`CFRunLoopRunSpecific + 406
frame #16: 0x0000000108d7e02f UIKit`-[UIApplication _run] + 468
frame #17: 0x0000000108d840d4 UIKit`UIApplicationMain + 159
frame #18: 0x0000000107df79cf TestDemo`main(argc=1, argv=0x00007fff57e085c0) at main.m:14
frame #19: 0x000000010b85865d libdyld.dylib`start + 1
(lldb)
watchpoint
這個斷點類型沒法通過界面添加而且很有用砰逻。使用watchpoint
可以用來觀察一個變量或者地址鸣驱,只要變量發(fā)生變化就觸發(fā)斷點。
有些時候蝠咆,我們會發(fā)現(xiàn)某個對象的值和我們預(yù)期的不一樣踊东,可是又不知道是哪個環(huán)節(jié)修改了這個值北滥,如果一個個的查會特別麻煩。而有了watchpoint
事情就簡單了闸翅。
但是它只能觀察這個指針本身再芋,不能指針指向的對象的變化,所以用處大大受限缎脾。比如watchpoint set variable button
,那么:button.backgroundColor = [UIColor blackColor];
不會觸發(fā)watchpoint
祝闻,而button = nil;
會變。
2017.6.8更新
1遗菠、 可以使用內(nèi)存直接打印联喘,比如輸出了一個按鈕:
Printing description of $18:
<UIButton: 0x7fdb44d16dc0; frame = (100 60; 100 40); opaque = NO; layer = <CALayer: 0x600000037140>>
這個是使用Debug View Hierarchy查看的時候,用鼠標(biāo)操縱打印的辙纬。如果你想看UIButton內(nèi)部的其他屬性怎么辦豁遭?比如查看enabled
屬性。
(lldb) po [0x7fdb44d16dc0 isEnabled]
0x0000000000000101
使用po + 執(zhí)行方法的形式贺拣,因為enabled
屬性的getter方法是isEnabled
,所以用了isEnabled
蓖谢,而不是enabled
。
2譬涡、 使用p/po命令來聲明一個變量:
Printing description of $9:
<UIButton: 0x7feadc520090; frame = (125 0; 125 40); opaque = NO; tag = 1001; layer = <CALayer:0x60000023aec0>>
(lldb) po id $myButton = [0x7feadc520090 self]
直接等于內(nèi)存地址是不行的闪幽,所以搞了個self
方法把對象返回。注意聲明變量的時候涡匀,前面是帶了一個符號$的,使用的時候也需要:
(lldb) po $myButton
<UIButton: 0x7feadc520090; frame = (125 0; 125 40); opaque = NO; tag = 1001; layer = <CALayer: 0x60000023aec0>>
有了這些盯腌,可以更方便的使用lldb來查看和探究對象的性質(zhì)了!陨瘩!