lldb language tip
19 May 2020I often find myself wanting lldb to evaluate an Objective-C expression when the current language is Swift. I’ve drastically improved my debugging experience by adding a couple of command aliases to make this a quick thing to do.
In my ~/.lldbinit
I’ve added the following:
command alias set-lang-objc settings set target.language objective-c
command alias set-lang-swift settings set target.language Swift
Why?
Here’s a couple concrete examples of how changing language can make things simpler
Calling private selectors from Swift
Calling non public selectors is a pain in Swift. A few selectors I commonly want to use are:
+[UIViewController _printHierarchy]
-[UIView recursiveDescription]
-[UIView _parentDescription]
-[NSObject _ivarDescription]
In order to call these in Swift I have to use value(forKey:)
- this is more characters to type and includes speech marks, which my fingers are generally slightly slower and more error prone at locating.
po UIViewController.value(forKey: "_printHierarchy")
po someView.value(forKey: "recursiveDescription")
Swapping the language to Objective-C removes a lot of the boilerplate typing:
set-lang-objc
po [UIViewController _printHierarchy]
po [someView recursiveDescription]
Calling methods in Swift when you only have a pointer address
Often I don’t have a variable in my current frame as I’m just grabbing memory addresses from other debug print commands or the view debugger (awesome use case).
Once you have a memory address in Swift you have to do the following to call a method:
po unsafeBitCast(0x7fd37e520f30, to: UIView.self).value(forKey: "recursiveDescription")
Changing the language to Objective-C this becomes considerably simpler:
set-lang-objc
po [0x7fd37e520f30 recursiveDescription]
One more thing…
In addition to the two aliases above I’ve had the following alias (that came from StackOverflow at some point) in my tool bag for a long time. It’s really helpful for single shot commands where I want to evaluate Objective-C without changing the language for subsequent commands.
Back in my ~/.lldbinit
I have:
command alias eco expression -l objective-c -o --
Which allows me to run a single command in Objective-C whilst the language is currently set to Swift
eco [0x7fd37e520f30 recursiveDescription]