通过runtime打印出对象所有属性的值

简介:

通过runtime打印出对象所有属性的值

今天给给大家提供的关于NSObject的category,通过runtime打印属性的值,相当有用哦,以后你再也不用每个对象都通过NSLog来逐个打印属性值了。

源码:

NSObject+Properties.h 与 NSObject+Properties.m

//
//  NSObject+Properties.h
//
//  Created by YouXianMing on 14-9-4.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface NSObject (Properties)

- (NSDictionary*)propertiesValues;

@end


//
//  NSObject+Properties.m
//
//  Created by YouXianMing on 14-9-4.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import "NSObject+Properties.h"
#import <objc/runtime.h>

@implementation NSObject (Properties)

- (NSDictionary*)propertiesValues
{
    // 获取属性列表
    NSArray *properties = [self propertyNames:[self class]];
    
    // 根据属性列表获取属性值
    return [self propertiesAndValuesDictionary:self properties:properties];
}

#pragma private - 私有方法

// 获取一个类的属性名字列表
- (NSArray*)propertyNames:(Class)class
{
    NSMutableArray  *propertyNames = [[NSMutableArray alloc] init];
    unsigned int     propertyCount = 0;
    objc_property_t *properties    = class_copyPropertyList(class, &propertyCount);
    
    for (unsigned int i = 0; i < propertyCount; ++i)
    {
        objc_property_t  property = properties[i];
        const char      *name     = property_getName(property);
        
        [propertyNames addObject:[NSString stringWithUTF8String:name]];
    }
    
    free(properties);
    
    return propertyNames;
}

// 根据属性数组获取该属性的值
- (NSDictionary*)propertiesAndValuesDictionary:(id)obj properties:(NSArray *)properties
{
    NSMutableDictionary *propertiesValuesDic = [NSMutableDictionary dictionary];
    
    for (NSString *property in properties)
    {
        SEL getSel = NSSelectorFromString(property);
        
        if ([obj respondsToSelector:getSel])
        {
            NSMethodSignature  *signature  = nil;
            signature                      = [obj methodSignatureForSelector:getSel];
            NSInvocation       *invocation = [NSInvocation invocationWithMethodSignature:signature];
            [invocation setTarget:obj];
            [invocation setSelector:getSel];
            NSObject * __unsafe_unretained valueObj = nil;
            [invocation invoke];
            [invocation getReturnValue:&valueObj];
            
            //assign to @"" string
            if (valueObj == nil)
            {
                valueObj = @"";
            }
            
            propertiesValuesDic[property] = valueObj;
        }
    }
    
    return propertiesValuesDic;
}

@end


//
//  NSObject+Properties.m
//
//  Created by YouXianMing on 14-9-4.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import "NSObject+Properties.h"
#import <objc/runtime.h>

@implementation NSObject (Properties)

- (NSDictionary*)propertiesValues
{
    // 获取属性列表
    NSArray *properties = [self propertyNames:[self class]];
    
    // 根据属性列表获取属性值
    return [self propertiesAndValuesDictionary:self properties:properties];
}

#pragma private - 私有方法

// 获取一个类的属性名字列表
- (NSArray*)propertyNames:(Class)class
{
    NSMutableArray  *propertyNames = [[NSMutableArray alloc] init];
    unsigned int     propertyCount = 0;
    objc_property_t *properties    = class_copyPropertyList(class, &propertyCount);
    
    for (unsigned int i = 0; i < propertyCount; ++i)
    {
        objc_property_t  property = properties[i];
        const char      *name     = property_getName(property);
        
        [propertyNames addObject:[NSString stringWithUTF8String:name]];
    }
    
    free(properties);
    
    return propertyNames;
}

// 根据属性数组获取该属性的值
- (NSDictionary*)propertiesAndValuesDictionary:(id)obj properties:(NSArray *)properties
{
    NSMutableDictionary *propertiesValuesDic = [NSMutableDictionary dictionary];
    
    for (NSString *property in properties)
    {
        SEL getSel = NSSelectorFromString(property);
        
        if ([obj respondsToSelector:getSel])
        {
            NSMethodSignature  *signature  = nil;
            signature                      = [obj methodSignatureForSelector:getSel];
            NSInvocation       *invocation = [NSInvocation invocationWithMethodSignature:signature];
            [invocation setTarget:obj];
            [invocation setSelector:getSel];
            NSObject * __unsafe_unretained valueObj = nil;
            [invocation invoke];
            [invocation getReturnValue:&valueObj];
            
            //assign to @"" string
            if (valueObj == nil)
            {
                valueObj = @"";
            }
            
            propertiesValuesDic[property] = valueObj;
        }
    }
    
    return propertiesValuesDic;
}

@end

使用详情:

测试用Model

//
//  YXModel.h
//  Test
//
//  Created by YouXianMing on 14-9-4.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface YXModel : NSObject

@property (nonatomic, strong) NSString      *name;
@property (nonatomic, strong) NSNumber      *age;
@property (nonatomic, strong) NSString      *sex;
@property (nonatomic, strong) NSDictionary  *info;

@end


//
//  YXModel.m
//  Test
//
//  Created by YouXianMing on 14-9-4.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import "YXModel.h"

@implementation YXModel

@end

使用:
//
//  AppDelegate.m
//  Test
//
//  Created by YouXianMing on 14-9-4.
//  Copyright (c) 2014年 YouXianMing. All rights reserved.
//

#import "AppDelegate.h"
#import "NSObject+Properties.h"
#import "YXModel.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // 初始化model
    YXModel *model = [YXModel new];
    
    // 赋值
    model.name     = @"YouXianMing";
    model.age      = @26;
    model.sex      = @"male";
    model.info     = @{@"A":@"B", @"C":@"D"};
    
    // 打印出所有属性的值
    NSLog(@"%@", model.propertiesValues);
    
    return YES;
}

@end

打印信息:

2014-09-04 19:39:08.913 Test[1278:60b] {

    age = 26;

    info =     {

        A = B;

        C = D;

    };

    name = YouXianMing;

    sex = male;

}

 

目录
相关文章
JAVA 将一个对象的所有字段值 赋给另一个 对象
JAVA 将一个对象的所有字段值 赋给另一个 对象
885 0
JAVA 将一个对象的所有字段值 赋给另一个 对象
定义好变量,${age}模版字符串,对象可以放null,检验数据类型console.log(typeof str)
定义好变量,${age}模版字符串,对象可以放null,检验数据类型console.log(typeof str)
|
6月前
|
测试技术
反射获取或修改对象属性的值
* 获取单个对象的所有键值对
53 3
|
前端开发 Java 数据库
SpringBoot返回枚举对象中的所有属性以对象的形式返回(一个@JSONType解决)
SpringBoot返回枚举对象中的所有属性以对象的形式返回(一个@JSONType解决)
797 0
java定义一个变量后调用该变量提示Unknown class
java定义一个变量后调用该变量提示Unknown class
对象的属性和值转换
对象的属性和值转换
40 0
|
Java
Java 反射修改类的常量值、静态变量值、属性值
Java 反射修改类的常量值、静态变量值、属性值
954 0
|
Java
Java中如何循环输出对象、属性和值【亲测可用】、反射机制
Java中如何循环输出对象、属性和值【亲测可用】、反射机制
784 0
lodash设置对象属性路径的值,可以根据函数定制值
lodash设置对象属性路径的值,可以根据函数定制值
142 0