What is the Swift equivalent of -NSObject description?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
The Swift equivalent of Objective-C's -[NSObject description] is the CustomStringConvertible protocol. Implementing its description property gives your type a custom text representation used by print(), string interpolation, and the debugger. For debug-only output, use CustomDebugStringConvertible with the debugDescription property, which mirrors Objective-C's -debugDescription.
CustomStringConvertible
Without CustomStringConvertible, print(user) outputs User(name: "Alice", age: 30) using Swift's default reflection — which is often sufficient for structs but unhelpful for classes.
CustomDebugStringConvertible
| Function | Protocol Used | Objective-C Equivalent |
print(obj) | CustomStringConvertible | NSLog(@"%@", obj) / -description |
debugPrint(obj) | CustomDebugStringConvertible | -debugDescription |
String(describing: obj) | CustomStringConvertible | [obj description] |
String(reflecting: obj) | CustomDebugStringConvertible | [obj debugDescription] |
NSObject Subclasses
For classes that inherit from NSObject, override the description property directly:
NSObject already conforms to CustomStringConvertible and CustomDebugStringConvertible, so you override instead of conforming.
Enums
Classes Without NSObject
Using in Collections
When objects conform to CustomStringConvertible, they display nicely in arrays and dictionaries:
LLDB Debugging
In Xcode's debugger (LLDB):
po (print object) uses debugDescription if available, falling back to description. This matches Objective-C's behavior where po calls -debugDescription.
Mirror API (Reflection)
For automatic property listing without manual description:
Structs get automatic reflection-based output from print(). Classes do not — they print the class name and memory address unless you implement description.
Common Pitfalls
- Forgetting
CustomStringConvertiblefor classes: Structs get a reasonable defaultprint()output. Classes withoutCustomStringConvertibleprint asClassNameor a memory address. Always implementdescriptionfor classes. - Using
descriptionindebugDescription: Avoidreturn descriptionindebugDescription— they serve different purposes.descriptionis user-facing;debugDescriptionshould include type name and internal state for debugging. - String interpolation calls
description:"\(myObject)"callsdescription, notdebugDescription. If you need the debug version in a string, useString(reflecting: myObject). - NSObject subclasses: Override
descriptionas a computed property (override var description: String), not as a method. Swift properties and Objective-C methods bridge automatically. - Expensive descriptions:
descriptionmay be called frequently (logging, debugging). Avoid expensive computations like network calls or database queries in thedescriptiongetter.
Summary
CustomStringConvertiblewithdescriptionis the Swift equivalent of-[NSObject description]CustomDebugStringConvertiblewithdebugDescriptionis the equivalent of-[NSObject debugDescription]print()usesdescription;debugPrint()and LLDB'spousedebugDescription- NSObject subclasses override
descriptiondirectly; pure Swift types conform to the protocol - Use
String(describing:)for user-facing strings andString(reflecting:)for debug output

