说说XcodeLLDB调试的那些事儿

使用场景之一,接收他人的项目,快速理清其层次结构,能够打标识符断点,以下图bash

viewDidLoadBreak

每个VC,都加了个在viewDidLoad方法处的断点,这样运行程序时,逐步断点,即可以理清层次,
可是,须要手动不断的继续,依旧不是很好
若是使用LLDB,就事半功倍~
先上效果图
LLDBDemoapp

LIDB简史

Xcode5以前的调试器使用的是GDB,若是你不幸使用,那感受简直了~而后伴随着Xcode5的发布,LLDB调试器取而代之,成为Xcode工程中默认的调试器,它和LVVM编译器一块儿,带给开发者丰富的流程控制和数据检测的调试功能.LLDB为Xcode提供了底层调试环境,其中,包括内嵌在Xcode IDE中的调试区域的控制面板,在这里咱们能够直接调用LLDB命令.ide

chisel facebook团队良心出品的LLDB扩展

chisel 安装(需已有Homebrew,其安装很易,如若困惑可私信,这里不展开说明)布局

brew update
 brew install chisel

安装结束后会打印出路径如 /usr/local/opt/chisel/libexec/fblldb.py
添加下述命令行到 ~/.lldbinit fileui

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

_注意:_要将将上述/path/to/fblldb.py,路径替换为安装成功后的打印出路径如:/usr/local/opt/chisel/libexec/fblldb.pyspa

特别的若是不存在~/.lldbinit file.
可使用touch ~/.lldbinit 来建立它.命令行

而后,须要重启Xcode,方能使之生效.3d

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的层级关系。code

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最经常使用的一些命令.固然这个不是所有,算是抛砖引玉.欢迎一块儿交流.

相关文章
相关标签/搜索