在 “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方法;
相比较而言,还是用类继承的方法实现比较简单,而且一旦出错,改动也极少,只要修改继承的类名就可以。
从这两种实现思路可以看出,代码越少,维护越好!