好玩的debugDescription(debug模式下調試model)
來自: http://www.jianshu.com/p/4e1f6938c1ca

description
在開發過程中, 往往會有很多的model來裝載屬性. 而在開發期間經常會進行調試查看model里的屬性值是否正確. 那么問題來了, 在 objective-c 里使用 NSLog("%@",model) 這行代碼打印出來的卻是 model 的地址. 不是我們所想要的結果~! 看圖:
那么問題又來了?有沒有辦法解決這個問題尼,答案那就是有~!只需要重寫 - (NSString *)description 方法即可。如下代碼:
</div>
.h文件
#import <Foundation/Foundation.h>@interface TestModel : NSObject @property (copy,nonatomic) NSString *text; @property (assign,nonatomic) NSInteger index; @end</pre>
.m文件
#import "TestModel.h"@implementation TestModel
(NSString *)description { return [NSString stringWithFormat:@"text:%@--index:%zi",self.text,self.index]; } @end</pre>
然后這時候在使用 NSLog("%@",model) 這行代碼就能打印我們想要的結果了。 看如下圖:
那么問題繼續來了...
如果model里有 N 多個屬性尼, 可能 10 個, 可能 20 個... 難道要在 description 方法里一個一個寫屬性并拼接返回? 你不嫌麻煩, 我光看著都蛋疼了... 所以我們可以采用 runtime 技術來動態獲取屬性并返回. 如下修改后的.m文件代碼:
</div>
修改后的.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</pre>
然后在打印 model , 如下圖:
這里寫圖片描述</div>
</div>
debugDescription
現在問題繼續來了..
在項目中 NSLog 語句往往也很多. 如果重寫 description 方法. 在控制臺則會打印出很多屬性. 看著就不舒服~~而且還有一個問題就是, 有時候我們其實并不需要打印 model 的屬性.. 那這樣重寫 description 方法反而 適得其反 了! 所有, 現在有一個解決方案就是重寫 debugDescription 方法
什么是 debugDescription ? 其實 debugDescription 和 description 是一樣的效果. 只不過唯一的區別就是 debugDescription 是在 Xcode 控制臺里使用 po 命令的時候調用的~!
而 debugDescription 的實現其實也就是調用了 description 方法而已
so, 在開發過程中并且 model 調試的時候, 筆者推薦重寫 debugDescription 方法而不是重寫 description 方法. 當需要打印 model 的屬性的時候, 在控制臺里使用 po 命令即可. 如下在此修改后的 .m文件
</div>
#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</pre>
看如下圖, 分別使用了 NSLog 和 po 命令的打印
這里寫圖片描述</div>
結果:
這里寫圖片描述</div>
這就達到了我們想要的效果, 如果需要打印 model 的屬性, 打個斷點然后使用 po 命令即可
</div>
demo地址
最后,附上本文章的一個小demo示例代碼,已放在github上。
https://github.com/DemoMania/DebugDescriptionDemo總結
- model 調試的時候, 推薦重寫 debugDescription 而不是 description
- 利用 runtime 技術動態獲取 class 的屬性
- 在 base 基類里重寫 debugDescription 方法,隨后所有model繼承與 baseModel 即可。
- 在重寫的 debugDescription 的方法里最好不要調用自身 debugDescription([self debugDescription])
</ul> </div>
本文由用戶 PhilShumate 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!相關經驗
相關資訊
sesese色