在lldb中打印Swift对象(po)会发生什么?

时间:2014-09-26 14:20:28

标签: objective-c cocoa swift lldb

Objective-C中,当您NSLog某个对象或po lldb时,该对象会收到description消息。

然而,在Swift中,行为似乎有所不同。我实现了Printable(需要description属性)和DebugPrintable(这需要一个名为debugDescription的属性)。如果我尝试println()一个对象或po,则不会调用这些属性。

发生了什么?那些协议是什么?

3 个答案:

答案 0 :(得分:6)

已知的问题是,Printable被Swift REPL忽略(即,Playground中的任何内容或在命令行中由xcrun swift运行)但是被编译器识别(编译的应用程序)在模拟器中或xcrun swiftc)。

例如,这里是" foo.swift"的代码:

struct Person : Printable {
    let name: String

    var description: String {
        return "\(name)"
    }
}

let me = Person(name: "Nate")
println(me)

如果我使用REPL运行它,我会得到这个:

$ xcrun swift foo.swift 
foo.Person

但是如果我先编译它,然后运行它,它会使用description计算属性:

$ xcrun -sdk macosx swiftc foo.swift ; ./foo
Nate

DebugPrintable协议非常有用,如果您希望能够在编译代码中使用debugPrintdebugPrintln函数,它们会打印出一个实例' s {{ 1}}属性。

答案 1 :(得分:4)

只需在Nate的回答中添加更多细节:

    Xcode 6中的
  • ,当你尝试" po"一个Swift对象,发生以下两种情况之一:

    • 该对象实际上是一个Objective-C对象(例如NSWindow,NSString),或者是这种类型的可选对象。在这种情况下,LLDB会在必要时解包,然后调用NSPrintForDebugger(objcpointer)。这意味着ObjC对象应该" po" Swift和Objective-C中的相同

    • 该对象实际上是一个Swift对象。在这种情况下,LLDB使用自己的数据格式化程序来打印对象,只需进行一些小的调整即可获得一个外观,但无论您的对象实现什么协议,它们都会被忽略

作为未来的增强,我们的想法是LLDB将能够向Swift标准库询问DebugString(对象),并让Swift库处理操作意味着的细节 - 就像目标中的NSPrintForDebugger()一样。 C世界。

在这个增强的Universe中,标准库的合同很可能是实现Printable或DebugPrintable会影响toDebugString()的结果。 LLDB会自动流行,因为它只是委派责任。

即使在这样一个增强的宇宙中,由于JIT的限制,您在REPL模式下的里程也会有所不同。顺便提一下,同样的限制使您无法在游乐场中定义类型并自定义其呈现方式(这需要实现至少一个Reflectable / Mirror协议)

答案 2 :(得分:0)

尝试:

dump(object)

了解更多信息here