說說XcodeLLDB調試的那些事兒


使用場景之一,接收他人的項目,快速理清其層次結構,可以打標識符斷點,如下圖

viewDidLoadBreak

每一個VC,都加了個在viewDidLoad方法處的斷點,這樣運行程序時,逐步斷點,便可以理清層次,
但是,需要手動不斷的繼續,依舊不是很好
如果使用LLDB,就事半功倍~
先上效果圖
LLDBDemo

LIDB簡史

Xcode5之前的調試器使用的是GDB,如果你不幸使用,那感覺簡直了~然后伴隨着Xcode5的發布,LLDB調試器取而代之,成為Xcode工程中默認的調試器,它和LVVM編譯器一起,帶給開發者豐富的流程控制和數據檢測的調試功能.LLDB為Xcode提供了底層調試環境,其中,包括內嵌在Xcode IDE中的調試區域的控制面板,在這里我們可以直接調用LLDB命令.

chisel facebook團隊良心出品的LLDB擴展

chisel 安裝(需已有Homebrew,其安裝很易,如若困惑可私信,這里不展開說明)

 brew update
 brew install chisel 

安裝結束后會打印出路徑如 /usr/local/opt/chisel/libexec/fblldb.py
添加下述命令行到 ~/.lldbinit file

 vi ~/.lldbinit
...
command script import /path/to/fblldb.py 

_注意:_要將將上述/path/to/fblldb.py ,路徑替換為安裝成功后的打印出路徑如:/usr/local/opt/chisel/libexec/fblldb.py

特別的如果不存在~/.lldbinit file.
可以使用touch ~/.lldbinit 來創建它.

然后,需要重啟Xcode,方能使之生效.

LLDB常見命令

Command Description iOS OS X
pviews Print the recursive view description for the key window. Yes Yes
pvc Print the recursive view controller description for the key window. Yes No
visualize Open a UIImage, CGImageRef, UIView, CALayer, NSData (of an image), UIColor, CIColor, or CGColorRef in Preview.app on your Mac. Yes No
fv Find a view in the hierarchy whose class name matches the provided regex. Yes No
fvc Find a view controller in the hierarchy whose class name matches the provided regex. Yes No
show/hide Show or hide the given view or layer. You don't even have to continue the process to see the changes! Yes Yes
mask/unmask Overlay a view or layer with a transparent rectangle to visualize where it is. Yes No
border/unborder Add a border to a view or layer to visualize where it is. Yes Yes
caflush Flush the render server (equivalent to a "repaint" if no animations are in-flight). Yes Yes
bmessage Set a symbolic breakpoint on the method of a class or the method of an instance without worrying which class in the hierarchy actually implements the method. Yes Yes
wivar Set a watchpoint on an instance variable of an object. Yes Yes
presponder Print the responder chain starting from the given object. Yes Yes
... ... and many more!

pviews

該命令是最常用的命令,主要是用來查看布局中view的層級關系的。

pviews
圖中command+R運行程序后,點擊暫停按鈕,就可進入lldb控制台,輸入pivews命令查看當前布局中view的層級關系。

border/unborder

這兩個命令分別是給要查看的view添加邊框和移除邊框,可以在lldb下輸入help border查看具體的用法,如果我要給第二個view添加一個顏色為藍色,寬度為2的邊框,之后再用unborder命令移除,操作如下:
border/unborder
通過help border命令知道border的使用格式如下:

Options:
--color/-c <color>; Type: string; A color name such as 'red', 'green',
 'magenta', etc.
 --width/-w <width>; Type: CGFloat; Desired width of border.
Syntax: border [--color=color] [--width=width] <viewOrLayer>

其中viewOrLayer表示你要修改的view的地址,我們通過pviews命令知道,第二個view的地址是0x7feae2d605f0,所以我們輸入

border -c blue -w 2 0x7feae2d605f0  //添加邊框
unborder 0x7feae2d605f0   //移除邊框

注意我在輸入每個border/unborder命令時,右側模擬器第二個view的變化。
view的層級關系。

pinternals

這個命令主要是打印view的內部詳細信息,太具體了,有需要的可以好好研究研究:
pinternals

(lldb) pinternals 0x7fa59c2446f0
(WKCompositingView) $451 = {
  UIView = {
    UIResponder = {
      NSObject = {
        isa = WKCompositingView
      }
      _hasAlternateNextResponder = false
      _hasInputAssistantItem = false
    }
    _constraintsExceptingSubviewAutoresizingConstraints = 0x00007fa59c248910 @"0 elements"
    _cachedTraitCollection = nil
    _layer = 0x00007fa599d81ba0
    _layerRetained = nil
    _gestureInfo = nil
    _gestureRecognizers = nil
    _subviewCache = 0x00007fa599f027d0 @"0 elements"
    _templateLayoutView = nil
    _charge = 0
    _tag = 0
    _viewDelegate = nil
    _backgroundColorSystemColorName = nil
    _countOfMotionEffectsInSubtree = 0
    _countOfTraitChangeRespondersInDirectSubtree = 0
    _cachedScreenScale = 2
    _retainCount = 4
    _tintAdjustmentDimmingCount = 0
    _shouldArchiveUIAppearanceTags = false
    _interactionTintColor = nil
    _layoutMarginsGuide = nil
    _minXVariable = 0x00007fa59c223790
    _minYVariable = 0x00007fa59c2237b0
    _boundsWidthVariable = 0x00007fa59c223ae0
    _boundsHeightVariable = 0x00007fa59c223800
    _layoutEngine = 0x00007fa59c014820
    _layoutDebuggingIdentifier = nil
    _internalConstraints = nil
    _continuousCornerRadius = 0
    _countOfFocusedAncestorTrackingViewsInSubtree = 0
    _semanticContentAttribute = 0
    __presentationControllerToNotifyOnLayoutSubviews = nil
    _previewingSegueTemplateStorage = nil
    _contentSizeNotificationToken = nil
    _readableContentGuide = 0x00007fee7c508a00
  }
}

pclass

這個可以查看view的層級關系

pclass

圖中先查看了UIView的層級關系,然后查看了一個第三方自定義的控件MMPlaceHolder的層級關系。

hide/show

這兩個命令顧名思義,就是顯示和隱藏某個指定的view,話不多說,上圖(注意模擬器中第二個view的變化):
hide/show

taplog

這個命令在你點擊屏幕后,lldb打印出你敲擊屏幕時接收事件的view的信息。

taplog

注意,我是先輸入的命令,然后點擊了屏幕才打印出對應view的信息。

pvc

這個命令是打印當前的控制器層級,如下圖,我定義了一個UINavigationController,ViewController作為它的根控制器。
pvc

bmessage

有這么中需求,在當前控制器沒有實現某個方法(譬如:-viewWillAppear:)方法,但是我又想在該方法調用時觸發中斷,這個時候bmessage就派上用場了

bmessage

(lldb) eobjc id $controller=(id)0x7fe8ab72ab50 //設置controller變量指向當前ViewController
(lldb) bmessage [$controller viewDidAppear:] //給當前ViewController設置斷點
Setting a breakpoint at -[UIViewController viewDidAppear:] with condition (void*)(id)$rdi == 0x00007fe8ab72ab50
Breakpoint 1: where = UIKit`-[UIViewController viewDidAppear:], address = 0x000000010e646d12

以上是Chisel最常用的一些命令.當然這個不是全部,算是拋磚引玉.歡迎一起交流.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM