iOS 高效开发-----实现description 方法 (续)
2015-05-20 10:55 PingKang 阅读(516) 评论(0) 编辑 收藏 举报在 “iOS 高效开发-----实现description 方法”这篇文章的最后,我留下了一个问题,就是,如果要给每个自定义的类覆写description方法和debugDescription方法 ,那将是一件非常庞大的工作量 ,因为自定义的类很多 ,而且每个自定义的类中的属性都会随着需求的修改出现变化 ,那么就又得修改这两个方法,那就变得无穷无尽了,永无宁日了,要么不用,要么就要找到更好得方法去用。
接下来,我们会用到动态运行时runtime。
我们先假设我们要处理的类中的属性都是OC的对象,实现的思路如下:
思路一:可以定义一个父类,在父类中实现description方法和debugDescription方法,然后令每一个类都成为其子类,具体实现如下:
// // PingkFather.h // LearnEffective2.0 // // Created by pk on 15/5/20. // Copyright (c) 2015年 iss. All rights reserved. // #import <Foundation/Foundation.h> @interface PingkFather : NSObject @end
// // PingkFather.m // LearnEffective2.0 // // Created by pk on 15/5/20. // Copyright (c) 2015年 iss. All rights reserved. // #import "PingkFather.h" #import <objc/runtime.h> @implementation PingkFather - (NSDictionary *) descriptionMehtod:(id)obj{ NSMutableDictionary * dic = [NSMutableDictionary dictionary]; u_int count; //获取所有的属性 objc_property_t *properties = class_copyPropertyList([obj class], &count); for (int i = 0; i<count; i++) { //得到属性的名称 const char * propertyName = property_getName(properties[i]); id objValue; //将属性转化位字符串 NSString * key = [NSString stringWithUTF8String:propertyName]; //取值 objValue = [obj valueForKey:key]; //写入字典中 [dic setObject:objValue forKey:key]; } NSDictionary * dictionary = [dic copy]; return dictionary; } -(NSString *)description { return [NSString stringWithFormat:@"%@",[self descriptionMehtod:self]]; } -(NSString *)debugDescription { return [NSString stringWithFormat:@"<%@: %p,%@>", [self class], self, [self descriptionMehtod:self]]; } @end
然后定义一个继承自PingkFather的子类,代码如下:
// // PingkSon.h // LearnEffective2.0 // // Created by pk on 15/5/20. // Copyright (c) 2015年 iss. All rights reserved. // #import "PingkFather.h" @interface PingkSon : PingkFather @property (nonatomic,copy,readonly)NSString * selfName; @property (nonatomic,copy,readonly)NSString * fatherName; @property (nonatomic,copy,readonly)NSString * motherName; - (id)initWithSelfName:(NSString *)selfName andFatherName:(NSString *)fatherName andMotherName:(NSString *)motherName; @end
// // PingkSon.m // LearnEffective2.0 // // Created by pk on 15/5/20. // Copyright (c) 2015年 iss. All rights reserved. // #import "PingkSon.h" @implementation PingkSon - (id)initWithSelfName:(NSString *)selfName andFatherName:(NSString *)fatherName andMotherName:(NSString *)motherName { if (self = [super init]) { _selfName = selfName; _fatherName = fatherName; _motherName = motherName; } return self; } @end
测试:
这种实现方法是最好的,也是最简单的,子类不用再实现任何代码。
另外一种思路,使用内敛函数,实现如下:
NS_INLINE NSDictionary * descriptionMehtod(id obj){ NSMutableDictionary * dic = [NSMutableDictionary dictionary]; u_int count; //获取所有的属性 objc_property_t *properties = class_copyPropertyList([obj class], &count); for (int i = 0; i<count; i++) { //得到属性的名称 const char * propertyName = property_getName(properties[i]); id objValue; //将属性转化位字符串 NSString * key = [NSString stringWithUTF8String:propertyName]; //取值 objValue = [obj valueForKey:key]; //写入字典中 [dic setObject:objValue forKey:key]; } NSDictionary * dictionary = [dic copy]; return dictionary; }
但是这种方法的话,不仅每个类要引入包含这个函数的头文件,而且每个类还要自己实现description方法和debugDescription方法;
相比较而言,还是用类继承的方法实现比较简单,而且一旦出错,改动也极少,只要修改继承的类名就可以。
从这两种实现思路可以看出,代码越少,维护越好!