在Objective-C
中,当您NSLog
某个对象或po
lldb
时,该对象会收到description
消息。
然而,在Swift中,行为似乎有所不同。我实现了Printable
(需要description
属性)和DebugPrintable
(这需要一个名为debugDescription
的属性)。如果我尝试println()
一个对象或po
,则不会调用这些属性。
发生了什么?那些协议是什么?
答案 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
协议非常有用,如果您希望能够在编译代码中使用debugPrint
和debugPrintln
函数,它们会打印出一个实例' s {{ 1}}属性。
答案 1 :(得分:4)
只需在Nate的回答中添加更多细节:
,当你尝试" 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)