When debugging a program, you often need to print and view object information. One way is to write code that prints all the attributes of an object to a log. The most common approach is something like this:

NSLog(@"object = %@", object);
Copy the code

1 When constructing a string to be printed to the log, object receives a description message. The description returned by this method replaces %@ in format String. For example, if object is an array, print its information with this code:

NSArray *object = @[@"A string", @(123)]; NSLog(@"object = %@", object); The output: object = ("A string", 123) However, if you do this on A custom class, the output should look like this: object = <EOCPerson: 0x7FD9a1600600 >Copy the code

This is less useful than the output when object is an array. Unless you override the Description method in your own class, the default method implemented by the NSObject class is called when you print the message. This method is defined in the NSObject protocol, but the NSObject class also implements it. Because NSObject is not the only “root class,” many methods need to be defined in the NSObject protocol. For example, NSProxy is also a “root class” that complies with the NSObject protocol. Because methods like description are defined in the NSObject protocol, “root classes” like NSProxy and their subclasses must implement them as well.

To output more useful information, it is easy to overwrite the description method and return a string describing the object. Such as:

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface MJPerson : NSObject

@property (nonatomic, copy, readonly) NSString *firstName;
@property (nonatomic, copy, readonly) NSString *lastName;

- (id)initWithFirstName: (NSString *)firstName lastName:(NSString *)lastName;

@end

NS_ASSUME_NONNULL_END

Copy the code
#import "MJPerson.h" @implementation MJPerson - (id)initWithFirstName: (NSString *)firstName lastName:(NSString *)lastName { if(self = [super init]){ _firstName = [firstName copy]; _lastName = [lastName copy]; } return self; } - (NSString *)description {return [NSString stringWithFormat:@"<%@: %p, \"%@ %@\">", [self class], self, _firstName, _lastName]; } @endCopy the code

The ZZBPerson object would output the following format if it were written like this:

#import "ViewController.h" #import "MJPerson.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; MJPerson *person = [[MJPerson alloc] initWithFirstName:@"Bob" lastName:@"Smith"]; NSLog(@"person = %@", person); <MJPerson: 0x600002109440, "Bob Smith">} @endCopy the code

It is clearly clearer and more useful than what was printed before overwriting.

Another method to note in the NSObject protocol is debugDescription, which is very similar in purpose to description. The difference is that the debugDescription method is invoked when the developer prints the object with a console command in the debugger. In the default implementation of the NSObject class, this method simply calls description directly.