美文网首页
WWDC2018-Xcode和lldb高级调试技巧

WWDC2018-Xcode和lldb高级调试技巧

作者: tom555cat | 来源:发表于2018-10-31 10:49 被阅读47次
    • 如何在LLDB中修改一个变量的值?
      使用expression xxx = newValue
    (lldb) po index
    100
    (lldb) expression index = 200
    (NSInteger) $1 = 200
    (lldb) po index
    200
    

    为了避免每次都在LLDB中修改变量值,可以编辑断点,在断点中增加Debugger Command类型的Action,expression index = 200

    • 如何不重新编译就查看代码的修改效果?
    1. 在代码中增加修改代码
    2. 在增加的修改代码处打断点
    3. 编辑断点,选择add action,增加”expression 增加的修改代码"
    
    • 使用Po命令查看参数
    po $arg1
    po (SEL)$arg2 查看selector
    po $arg3 查看参数
    
    • Symbolic Breakpoints的使用
      使用symbolic breakpoint能够进入任何方法或者函数。
      方法1
    通过断点导航栏点击Symbolic Breakpoints进入
    添加symbol,UIKit的函数通过OC方法“-[UILabel setText:]”,注意“-”和之后的“[]”中间没有空格。
    
      方法2
    在代码处添加断点并配置debug command,可以缩小符号断点的范围
    breakpoint set --one-shot true -name “-[UILabel setText:]”
    然后在左边导航栏选择下一帧就可以调到具体的代码处了。
    
    • 如何跳过一行代码,而不执行它?
      方法1
    在想要跳过的代码行处打断点,然后移动指令指针(即右边绿色的方框),跳过该行代码,然后点击继续执行。
    
      方法2:通过配置断点
    在想要跳过的行打断点,然后配置Debugger Command Action:
    thread jump —by 1
    如果跳过这行代码还想执行其他代码,可以再增加一个Debugger Command Action,并配置相应的expression。
    

    下图就是跳过了第二个label的text设置语句,然后发现“World”消失了。


    通过鼠标移动绿色instruction pointer跳过代码行
    没有跳过设置Label2文本代码行的执行结果 跳过设置Label2文本代码行的执行结果
    • po和p有什么区别?
    通过lldb的help查询:
    
    po
    
    (lldb) help po
    
         Evaluate an expression on the current thread.  Displays any returned value with formatting controlled by the type's author.  Expects 'raw'
    
         input (see 'help raw-input’.)
    
    'po' is an abbreviationfor 'expression -O  --'
    
    p
    
    (lldb) help p
    
         Evaluate an expression on the current thread.  Displays any returned value with LLDB's default formatting.  Expects 'raw' input (see 'help
    
         raw-input’.)
    
    'p' is an abbreviationfor 'expression --'
    

    po打印的是表达式作者所提供的debug描述信息,而p打印的是表达式lldb内置的信息。

    • watchpoints
    为一个变量添加watchpoint,当这个变量下次被改变时,触发断点。
    
    • 在控制台查看视图层级
    (lldb) expression -l objc -O -- [self.view recursiveDescription]
    
    其中-l指定通过何种语言来解析后面的表达式。
    
    <UIView: 0x7fd32ad22ca0; frame = (0 0; 414 896); autoresize = W+H; layer = <CALayer: 0x6000023a6120>>
    
       | <UILabel: 0x7fd32ad22920; frame = (0 0; 300 100); text = 'Hello'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x6000000dd2c0>>
    
       | <UILabel: 0x7fd32ad23900; frame = (300 0; 300 100); text = 'World'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x6000000dd400>>
    
    • Swift通过lldb修改视图布局
    Swift中无法通过地址来查看对象,仍然需要使用expression -l objc -O来查看地址来获取对象信息。
    
    在Swift中,可以通过unsafeBitCast(地址,to:类型)将内存地址转化为一个对象,可以通过这个对象获取相应的属性信息,而且可以进行修改。
    
    通过unsafeBitCast获取view类型的对象并修改frame后,可以通过“expression CATransaction.flush()”来查看修改效果。
    
    • Objective-C通过lldb修改视图布局:
    在Objective-C中,通过将内存机制强制转为为对象,
    
    (lldb) po ((UILabel *)0x7ff371d123a0).frame
    
    (origin = (x = 0, y = 0), size = (width = 300, height = 100))
    
    修改frame:
    
    (lldb) po ((UILabel *)0x7ff371d123a0).frame = CGRectMake(0, 300, 100, 100)
    
    (origin = (x = 0, y = 300), size = (width = 100, height = 100))
    
    使立即生效:
    
    (lldb) expression CATransaction.flush
    
    
    通过lldb修改Label1的frame

    相关文章

      网友评论

          本文标题:WWDC2018-Xcode和lldb高级调试技巧

          本文链接:https://www.haomeiwen.com/subject/fgiotqtx.html