现在的位置: 首页 > 综合 > 正文

反射解析

2014年01月30日 ⁄ 综合 ⁄ 共 3610字 ⁄ 字号 评论关闭

首先创建一个继承NSObject的类MyObject,因为用到了Obj-c运行时的相关方法,所以需要导入运行时的头文件。

#import <objc/runtime.h>

接着在.m里

接着就是解析数据啦

#pragma mark --------利用反射取得NSObject的属性,并存入到数组中
- (NSArray*)getPropertyList
{
    unsigned int outCount, i;
    
    objc_property_t *properties = class_copyPropertyList([self class], &outCount);
    
    NSMutableArray *keys = [[NSMutableArray alloc] initWithCapacity:outCount];
    
    for (i = 0; i < outCount; i++) {
        
        objc_property_t property = properties[i];
        
        NSString *propertyName = [[NSString alloc] initWithCString:property_getName(property) encoding:NSUTF8StringEncoding];
        [keys addObject:propertyName];
        
    }
    
    free(properties);
    
    return keys;
    
}
#pragma mark -----------完成对象的自动赋值
- (BOOL)reflectDataFromOtherObject:(NSObject*)dataSource
{
    BOOL ret = NO;
    
    for (NSString *key in [self getPropertyList]) {
        
        if ([dataSource isKindOfClass:[NSDictionary class]]) {
            
            ret = ([dataSource valueForKey:key]==nil)?NO:YES;
            
        }
        
        else
            
        {
            
            ret = [dataSource respondsToSelector:NSSelectorFromString(key)];
            
        }
        
        if (ret) {
            
            id propertyValue = [dataSource valueForKey:key];
            
            //该值不为NSNULL,并且也不为nil
            
            if (![propertyValue isKindOfClass:[NSNull class]] && propertyValue!=nil) {
                
                //解析字典类数据
                if([propertyValue isKindOfClass:[NSDictionary class]])
                {
                    [[self valueForKey:key] reflectDataFromOtherObject:propertyValue];
                }
                //解析数组类数组
                else if ([propertyValue isKindOfClass:[NSArray class]])
                {
                   //后面解释
                }
                else
                {
                    [self setValue:propertyValue forKey:key];
                }
                
            }
            
        }
        
    }
    
    return ret;
}

这样解析出来的数据如果是数组的话就赋值有点不是想要的,所以呢,需要再自己定影一个继承NSArray的MyArray

@interface MyArray : NSArray

@property(copy,nonatomic)NSString * subName;//元素的类型名

@property(strong,nonatomic)NSArray * data;//存放数据的数组

//初始化方法
-(id)initWithSubName:(NSString *)subName;

@end

subName主要是确定是哪个数组
data就是解析出来所要的数组

然后就是解析数组了,在MyObject里写上下面这个方法

#pragma mark ---------解析数组
- (MyArray *)analyzeArrayWithSource:(id)object
{
    MyArray * myArr = [[MyArray alloc] initWithSubName:self.subName];
    NSArray * data = object;
    //通过类名获取类类型
    Class subClass = NSClassFromString(myArr.subName);
    //判断类型是否为空类型
    if(subClass  != [NSNull class])
    {
        NSMutableArray * arr =[[NSMutableArray alloc]init];
        for (id obj in data) {
            //创建对象实体
            id subObject =[[subClass alloc] init];
            [subObject reflectDataFromOtherObject:obj];
            [arr addObject:subObject];
        }
        myArr.data = arr;
    }
    return myArr;
}

接着在

- (BOOL)reflectDataFromOtherObject:(NSObject*)dataSource

方法里解析数组那写上

[self setValue:[self
analyzeArrayWithSource:propertyValue] forKey:key];

对于该怎么给MyArray的subName传值,我是在MyObject里

@property(copy,nonatomic)NSString * subName;//元素的类型名

基本完成了。

下面给上我自己测试的例子:

将请求来的数据进行解析

NSString * str = [[NSStringalloc]initWithData:self.allDataencoding:NSUTF8StringEncoding];
    NSDictionary * dic = [str JSONValue];
    if (dic) {
        if ([[dicvalueForKey:@"statusCode"]isEqualToString:@"0000"]) {
            AllData * allData = [[AllDataalloc] initWithSubClass:self.subName];
            [allData reflectDataFromOtherObject:dic];
}
}

以下是AllData.h

#import <Foundation/Foundation.h>
#import "Resultlist.h"
#import "MyObject.h"

@interface AllData : MyObject

@property (copy, nonatomic) NSString * message;

@property (copy, nonatomic) NSString * statusCode;

@property (strong, nonatomic) Resultlist * addDatas;

//初始化方法
-(id)initWithSubClass:(NSString *)subClass;

@end

AllData.m

#import "AllData.h"

@implementation AllData

-(id)initWithSubClass:(NSString *)subClass
{
    self=[super init];
    if(self)
    {
        self.subName = subClass;
        self.addDatas = [[Resultlist alloc]initWithSubClass:subClass];
    }
    return self;
}

@end

Resultlist.h

#import <Foundation/Foundation.h>
#import "MyArray.h"
#import "MyObject.h"

@interface Resultlist : MyObject

@property (strong, nonatomic) MyArray * resultlist;//返回的数据实体

@property (assign, nonatomic) int totalrecord;//记录的总数

@property (assign, nonatomic) int count;//返回的记录的总数

//初始化方法
-(id)initWithSubClass:(NSString *)subClass;

@end

Resultlist.m

#import "Resultlist.h"

@implementation Resultlist

-(id)initWithSubClass:(NSString *)subClass
{
    self=[super init];
    if(self)
    {
        self.subName = subClass;
        self.resultlist = [[MyArray alloc]initWithSubName:subClass];
    }
    return self;
}

@end

像这样的一个JSON数据就解析出来了


抱歉!评论已关闭.