開發過程中有時需要存儲一些輕量級的數據,對於IOS提供的幾種數據存儲方式在這時最合適當屬對象歸檔:NSCoding
但是將對象數據進行歸檔解檔時候需要實現兩個方法: encodeWithCoder和initWithEncoder。encodeWithCoder就是編碼,initWithCoder就是解碼。
encodeWithCoder方法傳入的是一個NSCoder對象,實現的時候我們就可以調用encodeObject、encodeFloat、 encodeInt等各種方法並通過指定鍵值進行編碼,而
在需要的時候調用decodeDoubleForKey,decodeFloatForKey,decodeObjectForKey進行解碼。
1.實現encodeWithCoder和initWithEncoder
#import "MyModel.h" @implementation MyModel #define kCUSTIDKey @"CUSTIDKey" #define kCUSTSTATUSKey @"CUSTSTATUSKey" #define kPICTUREIDKey @"PICTUREIDKey" #define kUNITNUMKey @"UNITNUMKey" #define kCITYIDKey @"CITYIDKey" #define kCUSTNAMEKey @"CUSTNAMEKey" #define kCOMMUNITYNAMEKey @"COMMUNITYNAMEKey" #define kRESERVE1Key @"RESERVE1Key" #define kCITYKey @"CITYKey" #define kCOMMUNITYIDKey @"COMMUNITYIDKey" #define kCITYNAMEKey @"CITYNAMEKey" #define kBUILDINGNUMKey @"BUILDINGNUMKey" #define kNICKNAMEKey @"NICKNAMEKey" #define kHOUSENUMKey @"HOUSENUMKey" #define kPHONEKey @"PHONEKey" //歸檔 - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.CUSTID forKey:kCUSTIDKey]; [aCoder encodeObject:self.CUSTSTATUS forKey:kCUSTSTATUSKey]; [aCoder encodeObject:self.PICTUREID forKey:kPICTUREIDKey]; [aCoder encodeObject:self.UNITNUM forKey:kUNITNUMKey]; [aCoder encodeObject:self.PHONE forKey:kPHONEKey]; [aCoder encodeObject:self.CITYID forKey:kCITYIDKey]; [aCoder encodeObject:self.CUSTNAME forKey:kCUSTNAMEKey]; [aCoder encodeObject:self.COMMUNITYNAME forKey:kCOMMUNITYNAMEKey]; [aCoder encodeObject:self.RESERVE1 forKey:kRESERVE1Key]; [aCoder encodeObject:self.CITY forKey:kCITYKey]; [aCoder encodeObject:self.COMMUNITYID forKey:kCOMMUNITYIDKey]; [aCoder encodeObject:self.CITYNAME forKey:kCITYNAMEKey]; [aCoder encodeObject:self.BUILDINGNUM forKey:kBUILDINGNUMKey]; [aCoder encodeObject:self.NICKNAME forKey:kNICKNAMEKey]; [aCoder encodeObject:self.HOUSENUM forKey:kHOUSENUMKey]; } // 解檔 - (id)initWithCoder:(NSCoder *)decoder { if (self = [super init]) { self.CUSTID = [decoder decodeObjectForKey:kCUSTIDKey]; self.CUSTSTATUS = [decoder decodeObjectForKey:kCUSTSTATUSKey]; self.PICTUREID = [decoder decodeObjectForKey:kPICTUREIDKey]; self.PHONE = [decoder decodeObjectForKey:kPHONEKey]; self.UNITNUM = [decoder decodeObjectForKey:kUNITNUMKey]; self.CITYID = [decoder decodeObjectForKey:kCITYIDKey]; self.CUSTNAME = [decoder decodeObjectForKey:kCUSTNAMEKey]; self.COMMUNITYNAME = [decoder decodeObjectForKey:kCOMMUNITYNAMEKey]; self.RESERVE1 = [decoder decodeObjectForKey:kRESERVE1Key]; self.CITY = [decoder decodeObjectForKey:kCITYKey]; self.COMMUNITYID = [decoder decodeObjectForKey:kCOMMUNITYIDKey]; self.CITYNAME = [decoder decodeObjectForKey:kCITYNAMEKey]; self.BUILDINGNUM = [decoder decodeObjectForKey:kBUILDINGNUMKey]; self.NICKNAME = [decoder decodeObjectForKey:kNICKNAMEKey]; self.HOUSENUM = [decoder decodeObjectForKey:kHOUSENUMKey]; } return self; } @end
寫完之後發現整個人都不好了,如果對象屬性更多,這些重復性的代碼也意味著要被Command+C Command+V著N次,累覺無愛。
然後嘗試用其他方式進行,既然Objective-C運行時庫提供了非常便利的方法獲取其對象運行時所屬類及其所有成員變量,並通過KVC進行值的存取,那麼或者可以這樣objc/runtime+KVC
導入#import <objc/runtime.h>頭文件
//獲取類中所有屬性 unsigned int count; Ivar *varA = class_copyIvarList([MyModel class], &count); for (unsigned int i=0; i<count; i++) { Ivar v = varA[i]; const char *name = ivar_getName(v); NSLog(@"%s==",name); }
打印LOG:
好用,繼續,利用KVC進行取值,根據屬性名稱獲取對應的值
//KVC取值 id value = [self valueForKey:strName]; [encoder encodeObject:value forKey:strName];
最終改後的程序:
#import "MyModel.h" #import <objc/runtime.h> @implementation MyModel //解檔 - (id)initWithCoder:(NSCoder *)decoder { if (self = [super init]) { unsigned int count = 0; //獲取類中所有成員變量名 Ivar *ivar = class_copyIvarList([MyModel class], &count); for (int i = 0; i<count; i++) { Ivar iva = ivar[i]; const char *name = ivar_getName(iva); NSString *strName = [NSString stringWithUTF8String:name]; //進行解檔取值 id value = [decoder decodeObjectForKey:strName]; //利用KVC對屬性賦值 [self setValue:value forKey:strName]; } free(ivar); } return self; } //歸檔 - (void)encodeWithCoder:(NSCoder *)encoder { unsigned int count; Ivar *ivar = class_copyIvarList([MyModel class], &count); for (int i=0; i<count; i++) { Ivar iv = ivar[i]; const char *name = ivar_getName(iv); NSString *strName = [NSString stringWithUTF8String:name]; //利用KVC取值 id value = [self valueForKey:strName]; [encoder encodeObject:value forKey:strName]; } free(ivar); } @end
妥妥的了,遠離重復,做開心玩耍的程序媛!