今天在研究代码的时候,发现一个很有趣的函数,- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level 便研究了一下。
个人博客: https://linit.space
问题
比如我们有如下代码块
TestObj *object = [[TestObj alloc] init];
object.name1 = @"vname1";
object.name2 = @"vname2";
object.name3 = @"vname3";
object.name4 = @"vname4";
NSLog(@"%@",@[@"1",@"2",@{@"keyxx":@"value",@"key2":@"value2",@"key3":@{@"1":@"xxxx",@"dic":@{@"你好啊1":@"林某某!",@"你好啊2":@"林某某!",@"你好啊3":@"林某某!",@"你好啊4":@"林某某!",@"你好啊5":@"林某某!",@"你好啊6":@"林某某!",@"你好啊7":@"林某某!"},@"axaasx":@"3"},@"key4":@"value4"},@"3",object]);
打印的结果是
(
1,
2,
{
key2 = value2;
key3 = {
1 = xxxx;
axaasx = 3;
dic = {
"\U4f60\U597d\U554a1" = "\U6797\U67d0\U67d0\Uff01";
"\U4f60\U597d\U554a2" = "\U6797\U67d0\U67d0\Uff01";
"\U4f60\U597d\U554a3" = "\U6797\U67d0\U67d0\Uff01";
"\U4f60\U597d\U554a4" = "\U6797\U67d0\U67d0\Uff01";
"\U4f60\U597d\U554a5" = "\U6797\U67d0\U67d0\Uff01";
"\U4f60\U597d\U554a6" = "\U6797\U67d0\U67d0\Uff01";
"\U4f60\U597d\U554a7" = "\U6797\U67d0\U67d0\Uff01";
};
};
key4 = value4;
keyxx = value;
},
3,
"<TestObj: 0x7fb7fbc71520>"
)
中文直接用unicode编码打印出,自定义类的内容也不明确,导致查看的非常的不方便。
解决方案
实现description开头方法,为了更加使得打印结果更有格式,所以实现- (NSString )descriptionWithLocale:(id)locale indent:(NSUInteger)level。
==*注:优先级 - (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level > - (NSString *)description ,所以,例如NSDictionary,NSArray等,已经实现了- (NSString )descriptionWithLocale:(id)locale indent:(NSUInteger)level此方法,所以如果实现- (NSString )description则没有效果。==
原理
在使用NSObject类替换%@占位符时,会调用description相关方法,所以只要实现此方法,就可以起到修改打印内容的作用。因此对于系统的类,才用增加分类的方式实现,而自己的类,就是增加方法。
代码实现
#import <objc/runtime.h>
@interface TestObj : NSObject
@property (nonatomic, copy)NSString *name1;
@property (nonatomic, copy)NSString *name2;
@property (nonatomic, copy)NSString *name3;
@property (nonatomic, copy)NSString *name4;
@end
@implementation TestObj
- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
NSMutableString *mStr = [NSMutableString string];
NSMutableString *tab = [NSMutableString stringWithString:@""];
for (int i = 0; i < level; i++) {
[tab appendString:@"\t"];
}
[mStr appendFormat:@"<%@ = {\n",NSStringFromClass(self.class)];
unsigned int outCount;
objc_property_t *properties = class_copyPropertyList([self class], &outCount);
for (int i = 0; i < outCount; i++)
{
objc_property_t property = properties[i];
const char *charProperty = property_getName(property);
NSString *propertyName = [NSString stringWithUTF8String:charProperty];
if (propertyName) {
id propertyValue = [self valueForKey:propertyName];
NSString *lastSymbol = (outCount == i + 1) ? @"":@";";
if ([propertyValue respondsToSelector:@selector(descriptionWithLocale:indent:)]) {
[mStr appendFormat:@"\t%@%@ = %@%@\n",tab,propertyName,[propertyValue descriptionWithLocale:locale indent:level + 1],lastSymbol];
} else {
[mStr appendFormat:@"\t%@%@ = %@%@\n",tab,propertyName,propertyValue,lastSymbol];
}
}
}
free(properties);
[mStr appendFormat:@"%@}>",tab];
return mStr;
}
@end
@implementation NSDictionary (myTest)
- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
NSMutableString *mStr = [NSMutableString string];
NSMutableString *tab = [NSMutableString stringWithString:@""];
for (int i = 0; i < level; i++) {
[tab appendString:@"\t"];
}
[mStr appendString:@"{\n"];
NSArray *allKey = self.allKeys;
for (int i = 0; i < allKey.count; i++) {
id value = self[allKey[i]];
NSString *lastSymbol = (allKey.count == i + 1) ? @"":@";";
if ([value respondsToSelector:@selector(descriptionWithLocale:indent:)]) {
[mStr appendFormat:@"\t%@%@ = %@%@\n",tab,allKey[i],[value descriptionWithLocale:locale indent:level + 1],lastSymbol];
} else {
[mStr appendFormat:@"\t%@%@ = %@%@\n",tab,allKey[i],value,lastSymbol];
}
}
[mStr appendFormat:@"%@}",tab];
return mStr;
}
@end
@implementation NSArray (myTest)
- (NSString *)descriptionWithLocale:(id)locale indent:(NSUInteger)level
{
NSMutableString *mStr = [NSMutableString string];
NSMutableString *tab = [NSMutableString stringWithString:@""];
for (int i = 0; i < level; i++) {
[tab appendString:@"\t"];
}
[mStr appendString:@"(\n"];
for (int i = 0; i < self.count; i++) {
NSString *lastSymbol = (self.count == i + 1) ? @"":@",";
id value = self[i];
if ([value respondsToSelector:@selector(descriptionWithLocale:indent:)]) {
[mStr appendFormat:@"\t%@%@%@\n",tab,[value descriptionWithLocale:locale indent:level + 1],lastSymbol];
} else {
[mStr appendFormat:@"\t%@%@%@\n",tab,value,lastSymbol];
}
}
[mStr appendFormat:@"%@)",tab];
return mStr;
}
@end
结果
(
1,
2,
{
keyxx = value;
key3 = {
1 = xxxx;
dic = {
你好啊2 = 林某某!;
你好啊6 = 林某某!;
你好啊3 = 林某某!;
你好啊7 = 林某某!;
你好啊4 = 林某某!;
你好啊1 = 林某某!;
你好啊5 = 林某某!
};
axaasx = 3
};
key4 = value4;
key2 = value2
},
3,
<TestObj = {
name1 = vname1;
name2 = vname2;
name3 = vname3;
name4 = vname4
}>
)