Description & debug Description & runtime (debug mode debugging model)

Keywords: iOS Attribute xcode

description

In the development process, there are often many models to load attributes. During the development process, debugging is often carried out to check whether the attribute values in the model are correct. Then the problem arises. In objective-c, using NSLog("%@",model) line of code prints out the address of the model. Not the result we want ~!

So here comes the problem again? Is there any way to solve this problem? The answer is yes! Just rewrite the -(NSString*) description method. The following code:

.h file

#import <Foundation/Foundation.h>

@interface TestModel : NSObject
@property (copy,nonatomic) NSString *text;
@property (assign,nonatomic) NSInteger index;
@end

.m file

#import "TestModel.h"

@implementation TestModel
- (NSString *)description {
    return [NSString stringWithFormat:@"text:%@--index:%zi",self.text,self.index];
}
@end

Then we can print the results we want using the line NSLog("%@",model). Look at the following picture:

So the problem goes on.
If there are more than N attributes in the model, maybe 10, maybe 20... Should we write attributes one by one in the description method and stitch them back? You don't mind the trouble, I just look at them with pain.. So we can use runtime technology to dynamically acquire attributes and return them. The following modified. m file code:

Modified. m file

#import "TestModel.h"
#import <objc/runtime.h>//Import runtime header file

@implementation TestModel
- (NSString *)description {
    //Initialize a dictionary
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];

    //Get all the attributes of the current class
    uint count;
    objc_property_t *properties = class_copyPropertyList([self class], &count);

    //Cycle and use KVC to get the value of each attribute
    for (int i = 0; i<count; i++) {
        objc_property_t property = properties[i];
        NSString *name = @(property_getName(property));
        id value = [self valueForKey:name]?:@"nil";//The default value is nil string
        [dictionary setObject:value forKey:name];//Loaded into a dictionary
    }

    //release
    free(properties);

    //return
    return [NSString stringWithFormat:@"<%@: %p> -- %@",[self class],self,dictionary];
}
@end

Then print the model as follows:


Here's a picture description.

 

debugDescription

Now the problem continues.
NSLog statements are often plentiful in projects. If you override the description method, many attributes will be printed on the console. It's uncomfortable to look at it. ~ And there's also a problem that sometimes we don't actually need to print the model attributes.. That overrides the description method in reverse. So, there's a solution now to override the debug description method.

What is debug Description? In fact, debug Description and description are the same effect. The only difference is that debug Description is called when using the po command in the Xcode console.

The implementation of debugDescription actually calls the description method.

so, in the development process and model debugging, I recommend rewriting the debug description method rather than the description method. When you need to print the properties of the model, use the po command in the console. Here is the modified. m file.

#import "TestModel.h"
#import <objc/runtime.h>//Import runtime header file

@implementation TestModel

// Rewrite debugDescription, not description
- (NSString *)debugDescription {
    //Declare a dictionary
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];

    //Get all the attributes of the current class
    uint count;
    objc_property_t *properties = class_copyPropertyList([self class], &count);

    //Cycle and use KVC to get the value of each attribute
    for (int i = 0; i<count; i++) {
        objc_property_t property = properties[i];
        NSString *name = @(property_getName(property));
        id value = [self valueForKey:name]?:@"nil";//The default value is nil string
        [dictionary setObject:value forKey:name];//Loaded into a dictionary
    }

    //release
    free(properties);

    //return
    return [NSString stringWithFormat:@"<%@: %p> -- %@",[self class],self,dictionary];
}
@end

See the following figure, using the printing of NSLog and po commands, respectively


Here's a picture description.

Result:


Here's a picture description.

This achieves the desired effect. If you need to print the properties of the model, break the point and use the po command.

 

Posted by Space Cowboy on Fri, 14 Dec 2018 22:03:04 -0800