1.要想遍歷Model類的屬性魁袜,首先得通過Runtime來獲取該Model類有哪些屬性,輸出Model的所有屬性的值可不像遍歷Dictionary和Array那樣一個(gè)for循環(huán)搞定的雷绢,下面的方法是通過Runtime來獲取Model類的屬性字符串泛烙,并以數(shù)組的形式返回理卑。代碼如下:
一、獲取Model的實(shí)體屬性
1.要想遍歷Model類的屬性蔽氨,首先得通過Runtime來獲取該Model類有哪些屬性藐唠,輸出Model的所有屬性的值可不像遍歷Dictionary和Array那樣一個(gè)for循環(huán)搞定的,下面的方法是通過Runtime來獲取Model類的屬性字符串鹉究,并以數(shù)組的形式返回宇立。代碼如下:
///通過運(yùn)行時(shí)獲取當(dāng)前對(duì)象的所有屬性的名稱,以數(shù)組的形式返回
- (NSArray *) allPropertyNames{
///存儲(chǔ)所有的屬性名稱
NSMutableArray *allNames = [[NSMutableArray alloc] init];
///存儲(chǔ)屬性的個(gè)數(shù)
unsigned int propertyCount = 0;
///通過運(yùn)行時(shí)獲取當(dāng)前類的屬性
objc_property_t *propertys = class_copyPropertyList([self class], &propertyCount);
//把屬性放到數(shù)組中
for (int i = 0; i < propertyCount; i ++) {
///取出第一個(gè)屬性
objc_property_t property = propertys[i];
const char * propertyName = property_getName(property);
[allNames addObject:[NSString stringWithUTF8String:propertyName]];
}
///釋放
free(propertys);
return allNames;
}
2.獲取到Model類的屬性方法后需要把屬性字符串生成get方法自赔,我們可以執(zhí)行g(shù)et方法來獲取Model屬性的值妈嘹,下方的方法是根據(jù)屬性字符串來獲取屬性的getter方法,OC中屬性的getter方法的名字和屬性的名字是一致的绍妨,生成getter方法比較簡(jiǎn)單润脸,具體代碼如下:
#pragma mark -- 通過字符串來創(chuàng)建該字符串的Setter方法,并返回
- (SEL) creatGetterWithPropertyName: (NSString *) propertyName{
//1.返回get方法: oc中的get方法就是屬性的本身
return NSSelectorFromString(propertyName);
}
二他去、Get方法的執(zhí)行
接下來要做的是通過Runtime來執(zhí)行Getter方法毙驯,這一塊需要通過方法的簽名來執(zhí)行Getter方法。在OC的運(yùn)行時(shí)中要執(zhí)行的方法需要傳入?yún)?shù)或者需要接收返回值時(shí)灾测,需要通過方法的簽名來調(diào)用方法爆价。下面的代碼就是創(chuàng)建方法的簽名,然后通過簽名來獲取調(diào)用的對(duì)象媳搪,在下邊的方中回調(diào)用上述兩個(gè)方法在通過方法的簽名來獲取Model屬性的值铭段,具體代碼如下:
- (void) displayCurrentModleProperty{
//獲取實(shí)體類的屬性名
NSArray *array = [self allPropertyNames];
//拼接參數(shù)
NSMutableString *resultString = [[NSMutableString alloc] init];
for (int i = 0; i < array.count; i ++) {
//獲取get方法
SEL getSel = [self creatGetterWithPropertyName:array[i]];
if ([self respondsToSelector:getSel]) {
//獲得類和方法的簽名
NSMethodSignature *signature = [self methodSignatureForSelector:getSel];
//從簽名獲得調(diào)用對(duì)象
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
//設(shè)置target
[invocation setTarget:self];
//設(shè)置selector
[invocation setSelector:getSel];
//接收返回的值
NSObject *__unsafe_unretained returnValue = nil;
//調(diào)用
[invocation invoke];
//接收返回值
[invocation getReturnValue:&returnValue];
[resultString appendFormat:@"%@\\n", returnValue];
}
}
NSLog(@"%@", resultString);
}
執(zhí)行上述方法就可以輸入Model中的屬性的值,下面就在main函數(shù)中對(duì)Model賦完值后調(diào)用上述方法輸出一下Model的屬性值秦爆,調(diào)用代碼如下所示:
BeautifulGirlModel *beautifulGirl = [BeautifulGirlModel modelWithDictionary:data];
[beautifulGirl displayCurrentModleProperty];
運(yùn)行結(jié)果如下序愚,下面的輸出結(jié)果是Model中屬性的值。
三鲜结、Dictionary的Key與Model的屬性不同的處理方式
有時(shí)候會(huì)遇到字典的key和Model的屬性不一樣的情況展运,那么如何去解決這個(gè)問題呢活逆?最簡(jiǎn)單的做法是在具體的實(shí)體類中去維護(hù)一個(gè)映射關(guān)系方法,通過這個(gè)方法我們可以獲取相應(yīng)的的映射關(guān)系拗胜。
#pragma 返回屬性和字典key的映射關(guān)系
-(NSDictionary *) propertyMapDic{
return nil;
}
2.修改一下我們的便利初始化方法蔗候,在有映射字典的情況和沒有映射字典的情況下調(diào)用的方法是不一樣的,便利初始化方法的代碼如下:
- (instancetype)initWithDictionary: (NSDictionary *) data{
{
self = [super init];
if (self) {
if ([self propertyMapDic] == nil) {
[self assginToPropertyWithDictionary:data];
} else {
[self assginToPropertyWithNoMapDictionary:data];
}
}
return self;
}
}
3.接下來就將實(shí)現(xiàn)有映射關(guān)系要調(diào)用的方法埂软,這個(gè)方法就是通過映射關(guān)系把字典的key轉(zhuǎn)換成與property的名字一樣的字典锈遥,然后調(diào)用之前的賦值方法,具體代碼如下:
#pragma 根據(jù)映射關(guān)系來給Model的屬性賦值
-(void) assginToPropertyWithNoMapDictionary: (NSDictionary *) data{
///獲取字典和Model屬性的映射關(guān)系
NSDictionary *propertyMapDic = [self propertyMapDic];
///轉(zhuǎn)化成key和property一樣的字典勘畔,然后調(diào)用assginToPropertyWithDictionary方法
NSArray *dicKey = [data allKeys];
NSMutableDictionary *tempDic = [[NSMutableDictionary alloc] initWithCapacity:dicKey.count];
for (int i = 0; i < dicKey.count; i ++) {
NSString *key = dicKey[i];
[tempDic setObject:data[key] forKey:propertyMapDic[key]];
}
[self assginToPropertyWithDictionary:tempDic];
}
4.創(chuàng)建一個(gè)BadBoyModel, 并重寫propertyMapDic方法所灸,并且在propertyMapDic方法中給出映射關(guān)系并返回該映射關(guān)系對(duì)應(yīng)的字典。
(1)BadBoyModel的屬性如下:
//
// BadBoyModel.h
// BaseModelProject
//
// Created by Mr.LuDashi on 15/7/24.
// Copyright (c) 2015年 ludashi. All rights reserved.
//
#import "BaseModelObject.h"
@interface BadBoyModel : BaseModelObject
@property (nonatomic, copy) NSString *boy1;
@property (nonatomic, copy) NSString *boy2;
@property (nonatomic, copy) NSString *boy3;
@property (nonatomic, copy) NSString *boy4;
@end
(2)重寫映射方法炫七,映射字典的key是要轉(zhuǎn)換字典的key, Value是對(duì)應(yīng)Model的屬性名爬立。
//
// BadBoyModel.m
// BaseModelProject
//
// Created by Mr.LuDashi on 15/7/24.
// Copyright (c) 2015年 ludashi. All rights reserved.
//
#import "BadBoyModel.h"
@implementation BadBoyModel
#pragma 返回屬性和字典key的映射關(guān)系
-(NSDictionary *) propertyMapDic{
return @{@"keyBoy1":@"boy1",
@"keyBoy2":@"boy2",
@"keyBoy3":@"boy3",
@"keyBoy4":@"boy4",};
}
@end
5.在main函數(shù)中進(jìn)行測(cè)試
(1)生成我們的數(shù)值字典,字典的key與要賦值Model的屬性不同万哪,下面的循環(huán)就是要生成測(cè)試使用的數(shù)據(jù):
//生成Dic的Key與Model的屬性不一樣的字典侠驯。
NSMutableDictionary *data1 = [[NSMutableDictionary alloc] init];
//創(chuàng)建測(cè)試適用的字典
for(int i = 1; i <= 4; i ++){
NSString *key = [NSString stringWithFormat:@"keyBoy%d", i];
NSString *value = [NSString stringWithFormat:@"我是第%d個(gè)壞男孩", i];
[data1 setObject:value forKey:key];
}
(2) 實(shí)例化Model并輸出結(jié)果,當(dāng)然之前的代碼也是可以使用的奕巍。
BadBoyModel *badBoyModel = [BadBoyModel modelWithDictionary:data1];
[badBoyModel displayCurrentModleProperty];
運(yùn)行輸出結(jié)果如下:
這是小弟在51上看到的文章粘貼過來希望對(duì)你們有幫助我順便也收藏下來吟策。