假设我知道,根据早期的控制台输出,在某个内存位置是一个感兴趣的对象:
<MySpecialObject:0x7a5125a0 This is a description of my special object>
在ObjC调试器中,我可以执行po [0x7a5125a0 myMethod:arg1 arg2:arg2]
之类的操作来与调试器中的此对象进行交互。
我也可以这样做:
(lldb) expr MySpecialObject *$foo = 0x7a5125a0
(lldb) po [foo myMethod:arg1 arg2:arg2]
调试Swift程序时,实现此效果的方法是什么(在lldb中与对象进行交互,并给出其内存地址)?
答案 0 :(得分:23)
您可以尝试的一件事是:
(lldb) expr -l objc++ -O -- [(id)0xmyFancyAddressGoesHere selector]
你的里程可能会有所不同,但基本上这是你在ObjC中所做的美化版本(除了现在你在Swift-land中,所以你必须在ObjC模式下强制表达式评估器(-l objc ++),并且你不能依赖“po”别名,所以你需要明确要求“对象描述行为”(-O)
当然,如果你发现自己经常这样做,你可以为“expr -l objc ++ -O - ”创建自己的别名
答案 1 :(得分:10)
在Swift中,您使用unsafeBitcast
函数将内存地址转换为lldb中的变量。
expr $mv = unsafeBitCast(0x7a66cdb0, MapView.self)
这会将内存地址转换为MapVie
对象。当您构建自己的对象时,您可能会发现必须将import
项目的模块放入lldb。
Swift 4的更新:
似乎Xcode 10.1中的语法略有变化,因此unsafeBitCast
部分现在需要命名第二个参数,我们添加let
(或者var
取决于)。所以,上面的例子现在变成了
expr let $mv = unsafeBitCast(0x7a66cdb0, to: MapView.self)
答案 2 :(得分:4)
没有这样的方法。调试Swift几乎不是一个启动器。在暂停时对表达式和变量检查的评估完全被打破。最好现在使用println
或NSLog
。
编辑那是一年前的事了。 LLDB现在大大改进了与Swift的使用!
答案 3 :(得分:3)
版本6.1.1(6A2008a) 我正在调试视图层次结构。我有自己的UIImage视图子类。这就是它对我有用的方式:
(lldb) po 0x7fc6ecb55e30
<Lesson_1_Quartz_Composer.Layer: 0x7fc6ecb55e30; baseClass = UIImageView; frame = (0 0; 320 49.5); opaque = NO; gestureRecognizers = <NSArray: 0x7fc6ecb6df20>; layer = <CALayer: 0x7fc6ecb55f30>>
(lldb) po [0x7fc6ecb55e30 isUserInteractionEnabled]
0x0000000182002001
(lldb) po (bool)[0x7fc6ecb55e30 isUserInteractionEnabled]
true
(lldb) expr -l objc++ -O -- [(id)0x7fc6ecb55e30 isUserInteractionEnabled]
0x0000000182002001
显然它是一个UIView子类,所以它是objective-c,但它与Swift混合。