通过Rumtime实现打印/Po出模型值

作者: 再见远洋 | 来源:发表于2016-11-07 11:35 被阅读196次

    今天我们来谈一谈开发时的debug技巧吧,大家都知道,我们在开发中,使用NSLog("%@",你的模型),这样打印出来的是模型的地址:

    **2016-11-07 10:56:16.672 ****测试****[717:27180] <YJYYNewModel: 0x7fb211f13f80>**
    

    这个应该都经历过吧,可能遇到这种情况,一般我们会这么处理,打个断点,然后将鼠标放到写模型的的位置:

    屏幕快照 2016-11-07 上午10.56.06.png

    布吉岛你们看完上面的步骤作何感想,反正我是感觉好麻烦,主要是有时候你将鼠标放上面不一定出来,好了 ,还是不多说了,还是看看咱么怎么去做吧,一般遇到这种问题,我们的解决方案是通过重写 模型的- (NSString *)description方法:

    - (NSString *)description {
        
        return [NSString stringWithFormat:@"text:%@--index:%zi",self.name,self.age];
    }
    

    这时候我们再看打印:

    **2016-11-07 11:06:46.808 ****测试****[769:35597] text:****随便起的****--index:10**
    

    是不是灰常的神奇,好吧,这个方法,我相信很多人都是知道的,那么还是回到今天的主题,毕竟今天咱们是要用到运行时的,好像目前为止还没有用到Rumtime的地方,别急,马上就来了。

    我们再来假设一种情况,当我们的属性有非常非常多的的时候,假如30个,好吧,30个的情况应该也是有的,可能模型嵌套嘛,那这时候,我们该怎么处理?难道还是一个一个拼接吗?显然这不合理,那么我么很理所当然的就想到了Rumtime了,如下:

    //
    //  YJYYNewModel.m
    //  测试
    //
    //  Created by 遇见远洋 on 16/11/7.
    //  Copyright © 2016年 遇见远洋. All rights reserved.
    //
    
    #import "YJYYNewModel.h"
    #import <objc/runtime.h>
    
    @implementation YJYYNewModel
    
    - (NSString *)description {
        
         NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
        
        // 获取当前类的所有属性
        unsigned int count;// 记录属性个数
        objc_property_t *properties = class_copyPropertyList([self class], &count);
        for (int i = 0; i < count; i++) {
            
            // An opaque type that represents an Objective-C declared property.
            // objc_property_t 属性类型
            objc_property_t property = properties[i];
            // 获取属性的名称 C语言字符串
            const char *cName = property_getName(property);
            // 转换为Objective C 字符串
            NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
    
            id value = [self valueForKey:name]?:@"nil"; [dictionary setObject:value forKey:name];
            
             [dictionary setObject:value forKey:name];
        }
        return [NSString stringWithFormat:@"<%@: %p> -- %@",[self class],self,dictionary];
    }
    @end
    

    大功告成,此时你可能还会有一个问题,如果你不想打印这个模型的属性,但是由于你重写了description方法,所以每次打印就会看到一大堆烦人的log了,这时又该怎么办?其实苹果还是考虑的很周全的,除了提供description方法以外,它还提供了一个方法用于重写:- (NSString *)debugDescription {},通过重写这个方法,我们就可以解决上面的问题了。不过再写代码之前还是说下原理吧

    什么是debugDescription?

    其实debugDescription和description是一样的效果. 只不过唯一的区别就是debugDescription是在Xcode控制台里使用po命令的时候调用的,而debugDescription的实现其实也就是调用了description方法而已, 在开发过程中调试的时候,通过重写debugDescription方法就可以了,代码如下:

    - (NSString *)debugDescription {
        
         NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
        
        // 获取当前类的所有属性
        unsigned int count;// 记录属性个数
        objc_property_t *properties = class_copyPropertyList([self class], &count);
        for (int i = 0; i < count; i++) {
            
            // An opaque type that represents an Objective-C declared property.
            // objc_property_t 属性类型
            objc_property_t property = properties[i];
            // 获取属性的名称 C语言字符串
            const char *cName = property_getName(property);
            // 转换为Objective C 字符串
            NSString *name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
    
            id value = [self valueForKey:name]?:@"nil"; [dictionary setObject:value forKey:name];
            
             [dictionary setObject:value forKey:name];
        }
        return [NSString stringWithFormat:@"<%@: %p> -- %@",[self class],self,dictionary];
        
    }
    

    搞定收工!希望能帮到各位小伙伴..

    相关文章

      网友评论

      本文标题:通过Rumtime实现打印/Po出模型值

      本文链接:https://www.haomeiwen.com/subject/aixouttx.html