反射--> 解析JSON数据
程序员文章站
2022-04-14 13:27:31
方法一 Persons.json文件 Model.h类 Model.m类 调用 打印结果: 方法二 数据模型的父类是:JSONModel JSONModel的子类是:JSONPerson, JSONStudent, JSONTeacther等; JSONStudent.h中 注意:这是用OC来写的! ......
方法一
Persons.json文件
[ { "name": "Chris", "age": 18, "city": "Shanghai", "job": "iOS" }, { "name": "Ada", "age": 16, "city": "Beijing", "job": "student" }, { "name": "Rita", "age": 17, "city": "Xiamen", "job": "HR" } ]
Model.h类
1 #import <Foundation/Foundation.h> 2 3 @interface PersonModel : NSObject 4 5 @property (nonatomic, copy) NSString *name; 6 @property (nonatomic, assign) NSInteger age; 7 @property (nonatomic, copy) NSString *city; 8 @property (nonatomic, copy) NSString *job; 9 @property (nonatomic, copy) NSString *sex; 10 11 - (instancetype)initWithNSDictionary:(NSDictionary *)dict; 12 13 @end
Model.m类
1 #import "PersonModel.h" 2 #import <objc/runtime.h> 3 4 @implementation PersonModel 5 6 - (instancetype)initWithNSDictionary:(NSDictionary *)dict { 7 self = [super init]; 8 if (self) { 9 [self prepareModel:dict]; 10 } 11 return self; 12 } 13 14 - (void)prepareModel:(NSDictionary *)dict { 15 NSMutableArray *keys = [[NSMutableArray alloc] init]; 16 17 u_int count = 0; 18 objc_property_t *properties = class_copyPropertyList([self class], &count); 19 for (int i = 0; i < count; i++) { 20 objc_property_t property = properties[i]; 21 const char *propertyCString = property_getName(property); 22 NSString *propertyName = [NSString stringWithCString:propertyCString encoding:NSUTF8StringEncoding]; 23 [keys addObject:propertyName]; 24 } 25 free(properties); 26 27 for (NSString *key in keys) { 28 if ([dict valueForKey:key]) { 29 [self setValue:[dict valueForKey:key] forKey:key]; 30 } 31 } 32 } 33 34 @end
调用
1 NSString *file = [[NSBundle mainBundle] pathForResource:@"Persons" ofType:@"json"]; 2 NSData *data = [NSData dataWithContentsOfFile:file]; 3 NSMutableArray *array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; 4 5 for (NSDictionary *model in array) { 6 PersonModel *person = [[PersonModel alloc] initWithNSDictionary:model]; 7 NSLog(@"%@, %ld, %@, %@", person.name, (long)person.age, person.city, person.job); 8 }
打印结果:
方法二
数据模型的父类是:JSONModel
JSONModel的子类是:JSONPerson, JSONStudent, JSONTeacther等;
JSONStudent.h中
1 @import JSONModel; 2 3 @interface JSONStudent : JSONModel 4 5 @property (nonatomic, copy) NSString * id; 6 @property (nonatomic, copy) NSString * name; 7 @property (nonatomic, copy) NSString * nickName; 8 @property (nonatomic, copy) NSString * phoneNumber; 9 10 @end
注意:这是用OC来写的!
获取属性
1 func getAllProperties<T: JSONModel>(anyClass: T) -> [String] { 2 var properties = [String]() 3 let count = UnsafeMutablePointer<UInt32>.allocate(capacity: 0) 4 let buff = class_copyPropertyList(object_getClass(anyClass), count) 5 let countInt = Int(count[0]) 6 7 for i in 0..<countInt { 8 let temp = buff![i] 9 let tempPro = property_getName(temp) 10 let proper = String(utf8String: tempPro!) 11 properties.append(proper!) 12 } 13 return properties 14 15 }
注意:获取属性使用Swift写的,单纯用Swift和OC要简单!
使用
1 func returnListStudent(students: [JSONStudent]) { 2 for item in students { 3 let studentProperties = self.getAllProperties(anyClass: item) 4 for i in 0..< studentProperties.count{ 5 print("值是:\(item.value(forKey: studentProperties[I]))" + "属性是:\(studentProperties[i])"self.dataError) 6 } 7 } 8 }
方法三
User.swift
1 import UIKit 2 3 class User: NSObject { 4 var name:String = "" //姓名 5 var nickname:String? //昵称 6 var age:Int? //年龄 7 var emails:[String]? //邮件地址 8 }
Mirror
属性
// 实例化 let user = User() let mirror: Mirror = Mirror(reflecting:user) // subjectType:对象类型 print(mirror.subjectType) // 打印出:User // children:反射对象的属性集合 // displayStyle:反射对象展示类型 // advance 的使用 let children = mirror.children let p0 = advance(children.startIndex, 0, children.endIndex) // name 的位置 let p0Mirror = Mirror(reflecting: children[p0].value) // name 的反射 print(p0Mirror.subjectType) //Optional<String> 这个就是name 的类型
调用:
1 @objc func testOne() { 2 // 得到应用名称 3 let nameSpace = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as! String 4 let clsName = "User" 5 // 使用NSClassFromString通过类名得到实例(得到类的完整路径, 注意分隔符是小数点;并判断数据类型是否符合预期。 备注: as?后面的格式是类名.Type, cls可能是nil) 6 guard let cls = NSClassFromString(nameSpace + "." + clsName) as? NSObject.Type else { return } //得到类完整路径 7 print("------_>\(cls)") 8 let user = cls.init() 9 print("------111111_>\(user)") 10 11 // 使用Mirror得到属性值 12 let mirror = Mirror(reflecting: user) 13 for case let(key?, value) in mirror.children { 14 print("key:\(key), value: \(value)") //打印成员属性 15 } 16 print(mirror.subjectType) //反射对象的数据类型</span> 17 18 }
打印:
上一篇: 回调函数