不用斷點(diǎn)調(diào)試
如果你正在運(yùn)行 iOS app,你可以試試這個(gè): (因?yàn)槿肿兞渴强稍L問的)
(lldb) po [[[UIApplication sharedApplication] keyWindow] recursiveDescription]
<UIWindow: 0x7fbb61726ac0; frame = (0 0; 375 812); gestureRecognizers = <NSArray: 0x60c0002440b0>; layer = <UIWindowLayer: 0x60c000038c60>>
| <UILayoutContainerView: 0x7fbb61606620; frame = (0 0; 375 812); autoresize = W+H; gestureRecognizers = <NSArray: 0x608000058ea0>; layer = <CALayer: 0x600000421aa0>>
| | <UINavigationTransitionView: 0x7fbb6140a9f0; frame = (0 0; 375 812); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x608000033d20>>
| | | <UIViewControllerWrapperView: 0x7fbb61403b60; frame = (0 0; 375 812); autoresize = W+H; layer = <CALayer: 0x60800002fe80>>
| | | | <UIView: 0x7fbb6160b280; frame = (0 0; 375 812); autoresize = W+H; layer = <CALayer: 0x600000421ba0>>
| | | | | <UIView: 0x7fbb616044b0; frame = (100 100; 100 100); layer = <CALayer: 0x600000421ae0>>
| | | | | <UIButton: 0x7fbb61605cb0; frame = (200 200; 100 30); opaque = NO; layer = <CALayer: 0x600000421980>>
| | <UINavigationBar: 0x7fbb6171b9c0; frame = (0 44; 375 44); opaque = NO; autoresize = W; layer = <CALayer: 0x60c0000388e0>>
| | | <_UIBarBackground: 0x7fbb6171c1b0; frame = (0 -44; 375 88); userInteractionEnabled = NO; layer = <CALayer: 0x60c000038480>>
| | | | <UIImageView: 0x7fbb6171cea0; frame = (0 88; 375 0.333333); userInteractionEnabled = NO; layer = <CALayer: 0x60c000038940>>
| | | | <UIVisualEffectView: 0x7fbb6171d0d0; frame = (0 0; 375 88); layer = <CALayer: 0x60c000038960>>
| | | | | <_UIVisualEffectBackdropView: 0x7fbb61607b50; frame = (0 0; 375 88); autoresize = W+H; userInteractionEnabled = NO; layer = <UICABackdropLayer: 0x600000422560>>
| | | | | <_UIVisualEffectSubview: 0x7fbb61608dc0; frame = (0 0; 375 88); autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x600000422700>>
| | | <_UINavigationBarLargeTitleView: 0x7fbb6171e7e0; frame = (0 0; 0 44); clipsToBounds = YES; hidden = YES; layer = <CALayer: 0x60c000038cc0>>
| | | | <UILabel: 0x7fbb6171f580; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60c000282440>>
| | | <_UINavigationBarContentView: 0x7fbb6171db60; frame = (0 0; 375 44); layer = <CALayer: 0x60c0000389c0>>
| | | <_UINavigationBarModernPromptView: 0x7fbb61723c30; frame = (0 0; 0 44); alpha = 0; hidden = YES; layer = <CALayer: 0x60c000039b60>>
| | | | <UILabel: 0x7fbb61724050; frame = (0 25.3333; 0 0); text = ''; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60c000282760>>
有了上面的輸出,我們可以獲取這個(gè) view:
(lldb) e id $myView = (id)0x7fbb616044b0
然后在調(diào)試器中改變它的背景色:
(lldb) e (void)[$myView setBackgroundColor:[UIColor blueColor]]
但是只有程序繼續(xù)運(yùn)行之后才會(huì)看到界面的變化。因?yàn)楦淖兊膬?nèi)容必須被發(fā)送到渲染服務(wù)中,然后顯示才會(huì)被更新。
渲染服務(wù)實(shí)際上是一個(gè)另外的進(jìn)程 (被稱作 backboardd)。這就是說即使我們正在調(diào)試的內(nèi)容所在的進(jìn)程被打斷了,backboardd 也還是繼續(xù)運(yùn)行著的。
這意味著你可以運(yùn)行下面的命令,而不用繼續(xù)運(yùn)行程序:
(lldb) e (void)[CATransaction flush]
Push 一個(gè) View Controller
想象一個(gè)以 UINavigationController 為 root ViewController 的應(yīng)用。你可以通過下面的命令,輕松地獲取它:
(lldb) e id $nvc = [[[UIApplication sharedApplication] keyWindow] rootViewController]
然后 push 一個(gè) child view controller:
(lldb) e id $vc = [UIViewController new]
(lldb) e (void)[[$vc view] setBackgroundColor:[UIColor yellowColor]]
(lldb) e (void)[$vc setTitle:@"Yay!"]
(lldb) e (void)[$nvc pushViewContoller:$vc animated:YES]
最后運(yùn)行下面的命令:
e (void)[CATransaction flush]
navigation Controller 就會(huì)立刻就被 push 到你眼前。
查找按鈕的 target
想象你在調(diào)試器中有一個(gè) $myButton 的變量,可以是創(chuàng)建出來的,也可以是從 UI 上抓取出來的,或者是你停止在斷點(diǎn)時(shí)的一個(gè)局部變量。你想知道,按鈕按下的時(shí)候誰會(huì)接收到按鈕發(fā)出的 action。非常簡單:
(lldb) po [$myButton allTargets]
{(
<MagicEventListener: 0x7fb58bd2e240>
)}
(lldb) po [$myButton actionsForTarget:(id)0x7fb58bd2e240 forControlEvent:0]
<__NSArrayM 0x7fb58bd2aa40>(
_handleTap:
)
現(xiàn)在你或許想在它發(fā)生的時(shí)候加一個(gè)斷點(diǎn)。在 -[MagicEventListener _handleTap:] 設(shè)置一個(gè)符號(hào)斷點(diǎn)就可以了,在 Xcode 和 LLDB 中都可以,然后你就可以點(diǎn)擊按鈕并停在你所希望的地方了。