• iOS 高效开发-----实现description 方法 (续)


    在 “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方法;

    相比较而言,还是用类继承的方法实现比较简单,而且一旦出错,改动也极少,只要修改继承的类名就可以。

    从这两种实现思路可以看出,代码越少,维护越好!

  • 相关阅读:
    WebGoat之Injection Flaws
    WebGoat之Web Services
    XPath语法
    用Maven在Eclipse中配置Selenium WebDriver——方法1
    用Maven在Eclipse中配置Selenium WebDriver——方法2
    Enum与enum名字相互转换
    数据库数据类型varchar(n)与nvarchar(n)比较
    网页切图工具
    Html标签
    在VS的Solution Explorer中高亮当前编辑的文件
  • 原文地址:https://www.cnblogs.com/tianlin106/p/4516603.html
Copyright © 2020-2023  润新知