iOS:把对象直接转化成NSDictionary或JSON

2024-01-08 20:48

本文主要是介绍iOS:把对象直接转化成NSDictionary或JSON,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


iOS:把对象直接转化成NSDictionary或JSON

Mgen|2013-09-18 10:48|15515次浏览| IOS(296)开发(190)应用(36)对象(1)Dictionary(1) 0

1. 使用

实现的结果就是可以把任何对象转化成字典或者字典对应的JSON。字典的数据就是来自对象的属性名称和属性值 。而且是多层的,也就是说如果对象的某个属性值是另一个对象,数组,或者字典,该值都会被转换成另一个字典。

这个类型名称是PrintObject,它的所有方法都是静态的:

1
2
3
4
5
6
7
8
9
10
11
@interface PrintObject : NSObject
//通过对象返回一个NSDictionary,键是属性名称,值是属性值。
+ (NSDictionary*)getObjectData:(id)obj;
  
//将getObjectData方法返回的NSDictionary转化成JSON
+ (NSData*)getJSON:(id)obj options:(NSJSONWritingOptions)options error:(NSError**)error;
  
//直接通过NSLog输出getObjectData方法返回的NSDictionary
+ (void)print:(id)obj;
  
@end

举个例子,比如用来保存数据的类型是MyData, 这个类型如下定义:

1
2
3
4
5
6
7
8
9
@interface MyData : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *nullString;
@property (nonatomic) int age;
@property (nonatomic) BOOL male;
@property (nonatomic, strong) MyData *objProp;
@property (nonatomic, strong) NSArray *arrProp;
@property (nonatomic, strong) NSDictionary *dicProp;
@end

然后通过MyData类型创建一个复杂的对象,其中包含非对象属性,对象属性,还有包含对象的数组和字典。代码如下:

1
2
3
4
5
6
7
8
9
10
11
MyData *main = [[MyData alloc] init];
main.name = @ "mgen" ;
main.age = 22;
MyData *childOfChild = [[MyData alloc] init];
childOfChild.name = @ "child of child" ;
childOfChild.age = -443;
MyData *child = [[MyData alloc] init];
child.name = @ "child" ;
child.arrProp = @[@ "test" , @234, @[@123, @ "array in array" , childOfChild]];
main.objProp = child;
main.dicProp = @{@ "中文Key" : @3.444444, @ "object" : childOfChild};

OK,接着使用PrintObject类型输出这个MyData对象(上面的main变量)的字典:

1
2
NSDictionary *dic = [PrintObject getObjectData:main];
NSLog(@ "%@" , dic);

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{
     age = 22;
     arrProp = "<null>" ;
     dicProp =     {
         object =         {
             age = "-443" ;
             arrProp = "<null>" ;
             dicProp = "<null>" ;
             male = 0;
             name = "child of child" ;
             nullString = "<null>" ;
             objProp = "<null>" ;
         };
         "\U4e2d\U6587Key" = "3.444444" ;
     };
     male = 0;
     name = mgen;
     nullString = "<null>" ;
     objProp =     {
         age = 0;
         arrProp =         (
             test,
             234,
                         (
                 123,
                 "array in array" ,
                                 {
                     age = "-443" ;
                     arrProp = "<null>" ;
                     dicProp = "<null>" ;
                     male = 0;
                     name = "child of child" ;
                     nullString = "<null>" ;
                     objProp = "<null>" ;
                 }
             )
         );
         dicProp = "<null>" ;
         male = 0;
         name = child;
         nullString = "<null>" ;
         objProp = "<null>" ;
     };
}

也可以输出这个对象的JSON数据

1
2
3
NSData *jsonData = [PrintObject getJSON:main options:NSJSONWritingPrettyPrinted error:nil];
NSString *jsonText = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(@ "%@" , jsonText);

结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{
   "arrProp" : null ,
   "name" : "mgen" ,
   "age" : 22,
   "objProp" : {
     "arrProp" : [
       "test" ,
       234,
       [
         123,
         "array in array" ,
         {
           "arrProp" : null ,
           "name" : "child of child" ,
           "age" : -443,
           "objProp" : null ,
           "male" : 0,
           "nullString" : null ,
           "dicProp" : null
         }
       ]
     ],
     "name" : "child" ,
     "age" : 0,
     "objProp" : null ,
     "male" : 0,
     "nullString" : null ,
     "dicProp" : null
   },
   "male" : 0,
   "nullString" : null ,
   "dicProp" : {
     "中文Key" : 3.444444,
     "object" : {
       "arrProp" : null ,
       "name" : "child of child" ,
       "age" : -443,
       "objProp" : null ,
       "male" : 0,
       "nullString" : null ,
       "dicProp" : null
     }
   }
}

2. 实现

在实现上,属性的枚举是通过定义在<objc/runtime.h>中的class_copyPropertyList方法实现。其次,属性值的获取是通过KVC中的valueForKey方法,这个方法同时可以将非对象类型(如BOOL, int等)转换成NSNumber。

接着就是对数组,字典和对象类型值的嵌套处理,所有值就可以获取出来了。

至于JSON,如果正确获取了NSDictionary后,直接使用iOS 5后的NSJSONSerialization类型的dataWithJSONObject方法就可以返回包含JSON字符串的NSData对象了。

3. 下载和代码

源代码下载 下载页面 

注意:链接是微软SkyDrive页面,下载时请用浏览器直接下载,用某些下载工具可能无法下载 

源代码环境:Xcode 4.6.3

PrintObject.h

1
2
3
4
5
6
7
8
9
10
11
12
13
#import <Foundation/Foundation.h>
  
@interface PrintObject : NSObject
//通过对象返回一个NSDictionary,键是属性名称,值是属性值。
+ (NSDictionary*)getObjectData:(id)obj;
  
//将getObjectData方法返回的NSDictionary转化成JSON
+ (NSData*)getJSON:(id)obj options:(NSJSONWritingOptions)options error:(NSError**)error;
  
//直接通过NSLog输出getObjectData方法返回的NSDictionary
+ (void)print:(id)obj;
  
@end

PrintObject.m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#import "PrintObject.h"
#import <objc/runtime.h>
  
@implementation PrintObject
  
+ (NSDictionary*)getObjectData:(id)obj
{
     NSMutableDictionary *dic = [NSMutableDictionary dictionary];
     unsigned int propsCount;
     objc_property_t *props = class_copyPropertyList([obj class], &propsCount);
     for (int i = 0;i < propsCount; i++)
     {
         objc_property_t prop = props[i];
        
         NSString *propName = [NSString stringWithUTF8String:property_getName(prop)];
         id value = [obj valueForKey:propName];
         if (value == nil)
         {
             value = [NSNull null ];
         }
         else
         {
             value = [self getObjectInternal:value];
         }
         [dic setObject:value forKey:propName];
     }
     return dic;
}
  
+ (void)print:(id)obj
{
     NSLog(@ "%@" , [self getObjectData:obj]);
}
  
  
+ (NSData*)getJSON:(id)obj options:(NSJSONWritingOptions)options error:(NSError**)error
{
     return [NSJSONSerialization dataWithJSONObject:[self getObjectData:obj] options:options error:error];
}
  
+ (id)getObjectInternal:(id)obj
{
     if ([obj isKindOfClass:[NSString class]]
        || [obj isKindOfClass:[NSNumber class]]
        || [obj isKindOfClass:[NSNull class]])
     {
         return obj;
     }
    
     if ([obj isKindOfClass:[NSArray class]])
     {
         NSArray *objarr = obj;
         NSMutableArray *arr = [NSMutableArray arrayWithCapacity:objarr.count];
         for (int i = 0;i < objarr.count; i++)
         {
             [arr setObject:[self getObjectInternal:[objarr objectAtIndex:i]] atIndexedSubscript:i];
         }      
         return arr;
     }
    
     if ([obj isKindOfClass:[NSDictionary class]])
     {
         NSDictionary *objdic = obj;
         NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:[objdic count]];
         for (NSString *key in objdic.allKeys)
         {
             [dic setObject:[self getObjectInternal:[objdic objectForKey:key]] forKey:key];
         }     
         return dic;
    
     return [self getObjectData:obj];
}
  
@end
来自:cnblogs
分享到微信
0人喜欢 


这篇关于iOS:把对象直接转化成NSDictionary或JSON的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/584773

相关文章

SpringBoot排查和解决JSON解析错误(400 Bad Request)的方法

《SpringBoot排查和解决JSON解析错误(400BadRequest)的方法》在开发SpringBootRESTfulAPI时,客户端与服务端的数据交互通常使用JSON格式,然而,JSON... 目录问题背景1. 问题描述2. 错误分析解决方案1. 手动重新输入jsON2. 使用工具清理JSON3.

Springboot3+将ID转为JSON字符串的详细配置方案

《Springboot3+将ID转为JSON字符串的详细配置方案》:本文主要介绍纯后端实现Long/BigIntegerID转为JSON字符串的详细配置方案,s基于SpringBoot3+和Spr... 目录1. 添加依赖2. 全局 Jackson 配置3. 精准控制(可选)4. OpenAPI (Spri

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

Java中JSON格式反序列化为Map且保证存取顺序一致的问题

《Java中JSON格式反序列化为Map且保证存取顺序一致的问题》:本文主要介绍Java中JSON格式反序列化为Map且保证存取顺序一致的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录背景问题解决方法总结背景做项目涉及两个微服务之间传数据时,需要提供方将Map类型的数据序列化为co

Spring中管理bean对象的方式(专业级说明)

《Spring中管理bean对象的方式(专业级说明)》在Spring框架中,Bean的管理是核心功能,主要通过IoC(控制反转)容器实现,下面给大家介绍Spring中管理bean对象的方式,感兴趣的朋... 目录1.Bean的声明与注册1.1 基于XML配置1.2 基于注解(主流方式)1.3 基于Java

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以

C++类和对象之默认成员函数的使用解读

《C++类和对象之默认成员函数的使用解读》:本文主要介绍C++类和对象之默认成员函数的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、默认成员函数有哪些二、各默认成员函数详解默认构造函数析构函数拷贝构造函数拷贝赋值运算符三、默认成员函数的注意事项总结一

golang 对象池sync.Pool的实现

《golang对象池sync.Pool的实现》:本文主要介绍golang对象池sync.Pool的实现,用于缓存和复用临时对象,以减少内存分配和垃圾回收的压力,下面就来介绍一下,感兴趣的可以了解... 目录sync.Pool的用法原理sync.Pool 的使用示例sync.Pool 的使用场景注意sync.

SpringBoot项目中Redis存储Session对象序列化处理

《SpringBoot项目中Redis存储Session对象序列化处理》在SpringBoot项目中使用Redis存储Session时,对象的序列化和反序列化是关键步骤,下面我们就来讲讲如何在Spri... 目录一、为什么需要序列化处理二、Spring Boot 集成 Redis 存储 Session2.1