description
在開發過程中, 往往會有很多的model來裝載屬性. 而在開發期間經常會進行調試查看model里的屬性值是否正確. 那么問題來了, 在
objective-c
里使用NSLog("%@",model)
這行代碼打印出來的卻是model
的地址. 不是我們所想要的結果~! 看圖:
那么問題又來了?有沒有辦法解決這個問題尼,答案那就是有~!只需要重寫
- (NSString *)description
方法即可。如下代碼:
.h文件
#import <Foundation/Foundation.h>
@interface TestModel : NSObject
@property (copy,nonatomic) NSString *text;
@property (assign,nonatomic) NSInteger index;
@end
.m文件
#import "TestModel.h"
@implementation TestModel
- (NSString *)description {
return [NSString stringWithFormat:@"text:%@--index:%zi",self.text,self.index];
}
@end
然后這時候在使用
NSLog("%@",model)
這行代碼就能打印我們想要的結果了。 看如下圖:
那么問題繼續來了...
**如果model里有N
多個屬性尼, 可能10
個, 可能20
個... 難道要在description
方法里一個一個寫屬性并拼接返回? 你不嫌麻煩, 我光看著都蛋疼了... 所以我們可以采用runtime
技術來動態獲取屬性并返回. 如下修改后的.m文件代碼: **
修改后的.m文件
#import "TestModel.h"
#import <objc/runtime.h>//導入runtime頭文件
@implementation TestModel
- (NSString *)description {
//初始化一個字典
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
//得到當前class的所有屬性
uint count;
objc_property_t *properties = class_copyPropertyList([self class], &count);
//循環并用KVC得到每個屬性的值
for (int i = 0; i<count; i++) {
objc_property_t property = properties[i];
NSString *name = @(property_getName(property));
id value = [self valueForKey:name]?:@"nil";//默認值為nil字符串
[dictionary setObject:value forKey:name];//裝載到字典里
}
//釋放
free(properties);
//return
return [NSString stringWithFormat:@"<%@: %p> -- %@",[self class],self,dictionary];
}
@end
然后在打印
model
, 如下圖:這里寫圖片描述
</p>
</p>
debugDescription
現在問題繼續來了..
在項目中NSLog
語句往往也很多. 如果重寫description
方法. 在控制臺則會打印出很多屬性. 看著就不舒服~~而且還有一個問題就是, 有時候我們其實并不需要打印model
的屬性.. 那這樣重寫description
方法反而適得其反
了! 所有, 現在有一個解決方案就是重寫debugDescription
方法
什么是
debugDescription
? 其實debugDescription
和description
是一樣的效果. 只不過唯一的區別就是debugDescription
是在Xcode
控制臺里使用po
命令的時候調用的~!
而
debugDescription
的實現其實也就是調用了description
方法而已so, 在開發過程中并且
model
調試的時候, 筆者推薦重寫debugDescription
方法而不是重寫description
方法. 當需要打印model
的屬性的時候, 在控制臺里使用po
命令即可. 如下在此修改后的.m文件
#import "TestModel.h"
#import <objc/runtime.h>//導入runtime頭文件
@implementation TestModel
// 重寫debugDescription, 而不是description
- (NSString *)debugDescription {
//聲明一個字典
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
//得到當前class的所有屬性
uint count;
objc_property_t *properties = class_copyPropertyList([self class], &count);
//循環并用KVC得到每個屬性的值
for (int i = 0; i<count; i++) {
objc_property_t property = properties[i];
NSString *name = @(property_getName(property));
id value = [self valueForKey:name]?:@"nil";//默認值為nil字符串
[dictionary setObject:value forKey:name];//裝載到字典里
}
//釋放
free(properties);
//return
return [NSString stringWithFormat:@"<%@: %p> -- %@",[self class],self,dictionary];
}
@end
看如下圖, 分別使用了
NSLog
和po
命令的打印
這里寫圖片描述
結果:
這里寫圖片描述
這就達到了我們想要的效果, 如果需要打印
model
的屬性, 打個斷點然后使用po
命令即可
demo地址
最后,附上本文章的一個小demo示例代碼,已放在github上。
https://github.com/DemoMania/DebugDescriptionDemo
總結
model
調試的時候, 推薦重寫debugDescription
而不是description
- 利用
runtime
技術動態獲取class
的屬性 - 在
base
基類里重寫debugDescription
方法,隨后所有model繼承與baseModel
即可。 - 在重寫的
debugDescription
的方法里最好不要調用自身debugDescription([self debugDescription])