最近學習了歸檔與序列化的操做,在進行操做的時候須要爲每個類寫上歸檔以及反歸檔相關的操做 但屬性較多時這是一項費力不討好的事情 遂本身寫了個工具類,可以實現自動根據屬性個數進行自動序列反序列化操做java
主要運用了ios裏runtime的方法與屬性 其實在這裏是和java的反射機制是同樣的。ios
代碼總共分爲了兩種
工具
1.利用分類的方式實現 只須要拷貝分類進入工程 不須要進行其餘任何操做 由於分類會對全部的model起做用 因此還有第二種方式供參考學習
2.須要將NSObject繼承改成ZJAutoCoding繼承code
代碼以下,恭敬敬上~~~繼承
// // NSObject+ZJAutoCoding.h // // Created by Jason_Msbaby on 15/10/13. // Copyright © 2015年 張傑. All rights reserved. // #import <Foundation/Foundation.h> @interface NSObject (ZJAutoCoding) @end // // NSObject+ZJAutoCoding.m // // Created by Jason_Msbaby on 15/10/13. // Copyright © 2015年 張傑. All rights reserved. // #import "NSObject+ZJAutoCoding.h" #import <objc/runtime.h> @implementation NSObject (ZJAutoCoding) - (instancetype)initWithCoder:(NSCoder *)coder { //獲取全部屬性 unsigned int count = 0; objc_property_t *pros = class_copyPropertyList(self.class, &count); //遍歷屬性 for (int i = 0; i < count; i++) { objc_property_t pro = pros[i]; //當前屬性對應的名 NSString *proName = [NSString stringWithUTF8String:property_getName(pro)]; unsigned int c = 0; //獲取全部特徵 objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c); //遍歷全部特徵 for (int j = 0; j < c; j++ ) { objc_property_attribute_t attr = attrs[j]; //這裏的V指的是知道屬性對應的成員變量的名稱 例如name屬性 在這裏的特徵值則爲 V:_name 咱們須要的是_name if (strcmp(attr.name, "V") == 0) { //而後咱們須要獲取實例進行賦值操做 Ivar ivar = class_getInstanceVariable(self.class, attr.value); object_setIvar(self, ivar,[coder decodeObjectForKey:proName]); } } free(attrs); } free(pros); return [self init]; } -(void)encodeWithCoder:(NSCoder *)aCoder{ //獲取全部的屬性 unsigned int count = 0; objc_property_t *pros = class_copyPropertyList([self class], &count); //遍歷屬性 for (int i = 0; i < count; i++) { objc_property_t pro = pros[i]; unsigned int c = 0; //獲取實例變量的名稱 NSString *proName = [NSString stringWithUTF8String:property_getName(pro)]; //經過當前的屬性 獲取該屬性的特徵 objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c); //遍歷特徵 可以獲得其類型以及數值等內容 for (int j = 0; j < c; j++) { objc_property_attribute_t attr = attrs[j]; if (strcmp(attr.name, "V") == 0) {//若是是特徵的名稱 //獲取當前類對應特徵名稱的實例變量 Ivar ivar = class_getInstanceVariable(self.class, attr.value); //獲得該實例變量的數值 id object = object_getIvar(self, ivar); NSLog(@"%@",object); //歸檔 [aCoder encodeObject:object forKey:proName]; } } free(attrs); } free(pros); } @end -------------繼承的方式以下------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // // ZJAutoCoding.h // // Created by Jason_Msbaby on 15/10/13. // Copyright © 2015年 張傑. All rights reserved. // #import <Foundation/Foundation.h> /** 自動歸檔序列化 須要繼承該類 - returns: */ @interface ZJAutoCoding : NSObject <NSCoding> /** * 全自動動態加載屬性 實現反歸檔 * * @param coder * * @return */ - (instancetype)initWithCoder:(NSCoder *)coder; /** * 全自動動態加載屬性 實現歸檔 * * @param aCoder */ -(void)encodeWithCoder:(NSCoder *)aCoder; @end // // ZJAutoCoding.m // UI高級2 // // Created by Jason_Msbaby on 15/10/13. // Copyright © 2015年 張傑. All rights reserved. // #import "ZJAutoCoding.h" #import <objc/message.h> #import <objc/runtime.h> @implementation ZJAutoCoding - (instancetype)initWithCoder:(NSCoder *)coder { self = [super init]; if (self) { //獲取全部屬性 unsigned int count = 0; objc_property_t *pros = class_copyPropertyList(self.class, &count); //遍歷屬性 for (int i = 0; i < count; i++) { objc_property_t pro = pros[i]; //當前屬性對應的名 NSString *proName = [NSString stringWithUTF8String:property_getName(pro)]; unsigned int c = 0; //獲取全部特徵 objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c); //遍歷全部特徵 for (int j = 0; j < c; j++ ) { objc_property_attribute_t attr = attrs[j]; //這裏的V指的是知道屬性對應的成員變量的名稱 例如name屬性 在這裏的特徵值則爲 V:_name 咱們須要的是_name if (strcmp(attr.name, "V") == 0) { //而後咱們須要獲取實例進行賦值操做 Ivar ivar = class_getInstanceVariable(self.class, attr.value); object_setIvar(self, ivar,[coder decodeObjectForKey:proName]); } } free(attrs); } free(pros); } return self; } -(void)encodeWithCoder:(NSCoder *)aCoder{ //獲取全部的屬性 unsigned int count = 0; objc_property_t *pros = class_copyPropertyList([self class], &count); //遍歷屬性 for (int i = 0; i < count; i++) { objc_property_t pro = pros[i]; unsigned int c = 0; //獲取實例變量的名稱 NSString *proName = [NSString stringWithUTF8String:property_getName(pro)]; //經過當前的屬性 獲取該屬性的特徵 objc_property_attribute_t *attrs = property_copyAttributeList(pro, &c); //遍歷特徵 可以獲得其類型以及數值等內容 for (int j = 0; j < c; j++) { objc_property_attribute_t attr = attrs[j]; if (strcmp(attr.name, "V") == 0) {//若是是特徵的名稱 //獲取當前類對應特徵名稱的實例變量 Ivar ivar = class_getInstanceVariable(self.class, attr.value); //獲得該實例變量的數值 id object = object_getIvar(self, ivar); NSLog(@"%@",object); //歸檔 [aCoder encodeObject:object forKey:proName]; } } free(attrs); } free(pros); } @end