iOS開發之遍曆Model類的屬性並完善使用Runtime給Model類賦值,iosmodel

來源:互聯網
上載者:User

iOS開發之遍曆Model類的屬性並完善使用Runtime給Model類賦值,iosmodel

  在上篇部落格《iOS開發之使用Runtime給Model類賦值》中介紹了如何使用運行時在實體類的基類中添加給實體類的屬性賦值的方法,這個方法的前提是字典的Key必須和實體類的Property Name相同,然後通過運行時來產生和執行Setter方法給Model類的屬性賦值。

  通過Runtime來給Model類屬性賦值的好處是多多的,它便於代碼的後期維護,並且提高了開發效率。當你拿到解析後的字典時你不用一個一個的通過key去把字典的值賦值給相應的Model類的屬性,本篇部落格中會給出如何去遍曆Model中屬性的值,並且給出字典的Key和Model的屬性名稱不一樣的情況我們該如何負值。

  接下來會在上一個部落格代碼基礎上在Model基類中添加通過Runtime來遍曆Model類的屬性值。

  一、擷取Model的實體屬性

  1.要想遍曆Model類的屬性,首先得通過Runtime來擷取該Model類有哪些屬性,輸出Model的所有屬性的值可不像遍曆Dictionary和Array那樣一個for迴圈搞定的,下面的方法是通過Runtime來擷取Model類的屬性字串,並以數組的形式返回。代碼如下:

 1 ///通過運行時擷取當前對象的所有屬性的名稱,以數組的形式返回 2 - (NSArray *) allPropertyNames{ 3     ///儲存所有的屬性名稱 4     NSMutableArray *allNames = [[NSMutableArray alloc] init]; 5      6     ///儲存屬性的個數 7     unsigned int propertyCount = 0; 8      9     ///通過運行時擷取當前類的屬性10     objc_property_t *propertys = class_copyPropertyList([self class], &propertyCount);11     12     //把屬性放到數組中13     for (int i = 0; i < propertyCount; i ++) {14         ///取出第一個屬性15         objc_property_t property = propertys[i];16         17         const char * propertyName = property_getName(property);18         19         [allNames addObject:[NSString stringWithUTF8String:propertyName]];20     }21     22     ///釋放23     free(propertys);24     25     return allNames;26 }

 

  2.擷取到Model類的屬性方法後需要把屬性字串產生get方法,我們可以執行get方法來擷取Model屬性的值,下方的方法是根據屬性字串來擷取屬性的getter方法,OC中屬性的getter方法的名字和屬性的名字是一致的,產生getter方法比較簡單,具體代碼如下:

1 #pragma mark -- 通過字串來建立該字串的Setter方法,並返回2 - (SEL) creatGetterWithPropertyName: (NSString *) propertyName{3     4     //1.返回get方法: oc中的get方法就是屬性的本身5     return NSSelectorFromString(propertyName);6 }

 

  二、Get方法的執行

    接下來要做的是通過Runtime來執行Getter方法,這一塊需要通過方法的簽名來執行Getter方法。在OC的運行時中要執行的方法需要傳入參數或者需要接收傳回值時,需要通過方法的簽名來調用方法。下面的代碼就是建立方法的簽名,然後通過簽名來擷取調用的對象,在下邊的方中回調用上述兩個方法在通過方法的簽名來擷取Model屬性的值,具體代碼如下:

 1 - (void) displayCurrentModleProperty{ 2      3     //擷取實體類的屬性名稱 4     NSArray *array = [self allPropertyNames]; 5   6     //拼接參數 7     NSMutableString *resultString = [[NSMutableString alloc] init]; 8      9     for (int i = 0; i < array.count; i ++) {10         11         //擷取get方法12         SEL getSel = [self creatGetterWithPropertyName:array[i]];13         14         if ([self respondsToSelector:getSel]) {15             16             //獲得類和方法的簽名17             NSMethodSignature *signature = [self methodSignatureForSelector:getSel];18 19             //從簽名獲得調用對象20             NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];21 22             //設定target23             [invocation setTarget:self];24             25             //設定selector26             [invocation setSelector:getSel];27 28             //接收返回的值29             NSObject *__unsafe_unretained returnValue = nil;30 31             //調用32             [invocation invoke];33 34             //接收傳回值35             [invocation getReturnValue:&returnValue];36 37             [resultString appendFormat:@"%@\n", returnValue];38         }39     }40     NSLog(@"%@", resultString);41     42 }

 

  執行上述方法就可以輸入Model中的屬性的值,下面就在main函數中對Model賦完值後調用上述方法輸出一下Model的屬性值,調用代碼如下所示:

1         BeautifulGirlModel *beautifulGirl = [BeautifulGirlModel modelWithDictionary:data];2         3         [beautifulGirl displayCurrentModleProperty];

  

  運行結果如下,下面的輸出結果是Model中屬性的值。

  三、Dictionary的Key與Model的屬性不同的處理方式

    有時候會遇到字典的key和Model的屬性不一樣的情況,那麼如何去解決這個問題呢?最簡單的做法是在具體的實體類中去維護一個映射關係方法,通過這個方法我們可以擷取相應的的映射關係。

    1.在Model的基類中添加一個返回映射字典的一個方法,然後在子類中進行重寫,這個映射方法在基類中返回nil, 如果子類需要重寫的話就對這個方法進行重寫並返回映射字典。方法如下:

1 #pragma 返回屬性和字典key的映射關係2 -(NSDictionary *) propertyMapDic{3     return nil;4 }

 

  2.修改一下我們的便利初始化方法,在有映射字典的情況和沒有映射字典的情況下調用的方法是不一樣的,便利初始化方法的代碼如下:

 1 - (instancetype)initWithDictionary: (NSDictionary *) data{ 2     { 3         self = [super init]; 4         if (self) { 5             if ([self propertyMapDic] == nil) { 6                 [self assginToPropertyWithDictionary:data]; 7             } else { 8                 [self assginToPropertyWithNoMapDictionary:data]; 9             }10         }11         return self;12     }13 }

 

  3.接下來就將實現有映射關係要調用的方法,這個方法就是通過映射關係把字典的key轉換成與property的名字一樣的字典,然後調用之前的賦值方法,具體代碼如下:

 1 #pragma 根據映射關係來給Model的屬性賦值 2 -(void) assginToPropertyWithNoMapDictionary: (NSDictionary *) data{ 3     ///擷取字典和Model屬性的映射關係 4     NSDictionary *propertyMapDic = [self propertyMapDic]; 5      6     ///轉化成key和property一樣的字典,然後調用assginToPropertyWithDictionary方法 7      8     NSArray *dicKey = [data allKeys]; 9 10     11     NSMutableDictionary *tempDic = [[NSMutableDictionary alloc] initWithCapacity:dicKey.count];12     13     for (int i = 0; i < dicKey.count; i ++) {14         NSString *key = dicKey[i];15         [tempDic setObject:data[key] forKey:propertyMapDic[key]];16     }17     18     [self assginToPropertyWithDictionary:tempDic];19     20 }

 

  4.建立一個BadBoyModel, 並重寫propertyMapDic方法,並且在propertyMapDic方法中給出映射關係並返回該映射關係對應的字典。

    (1)BadBoyModel的屬性如下:

 1 // 2 //  BadBoyModel.h 3 //  BaseModelProject 4 // 5 //  Created by Mr.LuDashi on 15/7/24. 6 //  Copyright (c) 2015年 ludashi. All rights reserved. 7 // 8  9 #import "BaseModelObject.h"10 11 @interface BadBoyModel : BaseModelObject12 13 @property (nonatomic, copy) NSString *boy1;14 @property (nonatomic, copy) NSString *boy2;15 @property (nonatomic, copy) NSString *boy3;16 @property (nonatomic, copy) NSString *boy4;17 18 @end

 

    (2)重寫映射方法,映射字典的key是要轉換字典的key, Value是對應Model的屬性名稱。

 1 // 2 //  BadBoyModel.m 3 //  BaseModelProject 4 // 5 //  Created by Mr.LuDashi on 15/7/24. 6 //  Copyright (c) 2015年 ludashi. All rights reserved. 7 // 8  9 #import "BadBoyModel.h"10 11 @implementation BadBoyModel12 13 #pragma 返回屬性和字典key的映射關係14 -(NSDictionary *) propertyMapDic{15     return @{@"keyBoy1":@"boy1",16              @"keyBoy2":@"boy2",17              @"keyBoy3":@"boy3",18              @"keyBoy4":@"boy4",};19 }20 21 @end

 

    5.在main函數中進行測試

      (1)、產生我們的數值字典,字典的key與要賦值Model的屬性不同,下面的迴圈就是要產生測試使用的資料:

 1        //產生Dic的Key與Model的屬性不一樣的字典。 2          3         NSMutableDictionary *data1 = [[NSMutableDictionary alloc] init]; 4          5         //建立測試適用的字典 6         for(int i = 1; i <= 4; i ++){ 7             NSString *key = [NSString stringWithFormat:@"keyBoy%d", i]; 8              9             NSString *value = [NSString stringWithFormat:@"我是第%d個壞男孩", i];10             11             [data1 setObject:value forKey:key];12         }

 

      (2) 執行個體化Model並輸出結果,當然之前的代碼也是可以使用的。

1         BadBoyModel *badBoyModel = [BadBoyModel modelWithDictionary:data1];2         3         [badBoyModel displayCurrentModleProperty];

 

    運行輸出結果如下:

  

 

    今天部落格就到這,至此,Model的基類最基本的方法封裝的也就差不多了,根據具體需求可以在添加新的方法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.