Say you have a custom object which has a custom description like so:
class CustomObject {
var customDescription: String {
return "Title: Hello, \n Subtitle: World"
}
}
Is there a way to have the line break \n
work in the console when printing it using the po
command in the LLDB console?
Right now LLDB prints the \n
as part of the text and doesn't process it:
po object.customDescription
> "Title: Hello, \n Subtitle: World"
Where the desired result is:
po object.customDescription
> Title: Hello
Subtitle: World
Do you have any solution for this?
I don't want to discourage you from making an lldb data formatter for your classes. They have the advantage over po
that they give lldb a way to show you a summary representation of your data without having to call code in the running program. Also, if you use Xcode, the Xcode locals view will show your data formatters automatically.
But to clear up the way po
works:
The lldb po
command works by calling the language-specified description method for the object that the expression you provide resolves to. So for instance in your example, you were seeing the result of the description method for the Swift String class, which displays the "programmer's view" of the string.
In the case of Swift, there are a couple of ways to provide a description. The simplest is to implement the CustomStringConvertible protocol:
class CustomObject : CustomStringConvertible {
var description: String {
return "Title: Hello,\n Subtitle: World"
}
}
func main()
{
let my_object = CustomObject()
print (my_object)
}
main()
Then when you debug this, you see:
(lldb) br s -p print
Breakpoint 1: where = desc`desc.main() -> () + 27 at desc.swift:11, address = 0x000000010000116b
(lldb) run
Process 69112 launched: '/private/tmp/desc' (x86_64)
Process 69112 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x000000010000116b desc`desc.main() -> () at desc.swift:11
8 func main()
9 {
10 let my_object = CustomObject()
-> 11 print (my_object)
^
12 }
13
14 main()
Target 0: (desc) stopped.
(lldb) po my_object
Title: Hello,
Subtitle: World
(lldb) c
Process 69112 resuming
Title: Hello,
Subtitle: World
Process 69112 exited with status = 0 (0x00000000)
Note here that both po
and the swift print
function render your object the same way.
If you want separate debug and print descriptions, then you also implement CustomDebugStringConvertible
which requires a debugDescription
property. Then po
will print the debugDescription
but print
will print the description
.
If you want to get fancier, or want to have po represent the "structure" of your object the way the po
result for Swift Arrays (for example) does, you can make a custom Mirror
for your class. There's documentation on that here:
https://developer.apple.com/documentation/swift/mirror
and if that isn't clear, the implementation of Mirrors is in the swift sources in:
https://github.com/apple/swift/blob/master/stdlib/public/core/Mirror.swift