zoukankan      html  css  js  c++  java
  • 说说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最常用的一些命令.当然这个不是全部,算是抛砖引玉.欢迎一起交流.

  • 相关阅读:
    CPU,MPU,MCU,SOC,SOPC联系与差别
    中央处理器
    手机CPU
    手机CPU天梯图2018年5月最新版
    Ubuntu输入法切换问题
    说说C与汇编之间的互相联系(转)
    MDK972-EK开发板裸调试设置和裸机程序烧写(转)
    来,打一下五笔的字根表
    64位debian系统下安装inodeClient
    计算机网络——链路层协议
  • 原文地址:https://www.cnblogs.com/jiahao89/p/6142437.html
Copyright © 2011-2022 走看看