lldb language tip

I 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]