iOS 自定義對象及子類及模型套模型的拷貝、歸檔存儲的通用代碼


一、runtime實現通用copy

如果自定義類的子類,模型套模型你真的會copy嗎,小心有坑。

copy需要自定義類繼承NSCopying協議

#import <objc/runtime.h>

- (id)copyWithZone:(NSZone *)zone {
    
    id obj = [[[self class] allocWithZone:zone] init];
    Class class = [self class];
    while (class != [NSObject class]) {
        unsigned int count;
        Ivar *ivar = class_copyIvarList(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] copy];//如果還套了模型也要copy呢
            [obj setValue:value forKey:strName];
        }
        free(ivar);
        
        class = class_getSuperclass(class);//記住還要遍歷父類的屬性呢
    }
    return obj;
}

二、runtime實現通用歸檔解檔

歸檔解檔需要自定義類繼承NSCoding協議

#import <objc/runtime.h>

#pragma
mark - 歸檔、解檔 - (void)encodeWithCoder:(NSCoder *)encoder { Class class = [self class]; while (class != [NSObject class]) { unsigned int count; Ivar *ivar = class_copyIvarList(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); class = class_getSuperclass(class);//記住還要遍歷父類的屬性呢 } } - (id)initWithCoder:(NSCoder *)decoder { self = [super init]; if (self) { Class class = [self class]; while (class != [NSObject class]) { unsigned int count = 0; //獲取類中所有成員變量名 Ivar *ivar = class_copyIvarList(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); class = class_getSuperclass(class);//記住還要遍歷父類的屬性呢 } } return self; }

三、NSUserDefaults存儲自定義對象

//1.自定義類繼承NSCoding協議,並實現歸檔解檔,前面介紹過了,不多說

//2.將自定義對象轉NSData
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:student];

//3.存到NSUserDefaults
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"myStudent"];
[[NSUserDefaults standardUserDefaults] synchronize];//這句要寫,很多人都忘了

//4.存數組,數組中包含自定義對象
[dataArray addObject:data];//這個data是第2步歸檔得到的data

//5.NSUserDefaults只能存不可變數組,不要忘了轉換成不可變
NSArray * array = [NSArray arrayWithArray:dataArray];
[[NSUserDefaults standardUserDefaults] setObject:array forKey:@"students"];

四、NSUserDefaults中讀取歸檔的自定義對象

NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"myStudent"];
Student *student = [NSKeyedUnarchiver unarchiveObjectWithData:data];

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM