ios 歸檔和解歸檔(利用runtime)

前言

iOS存取數(shù)據(jù)的方式有幾種,這次項(xiàng)目中存儲(chǔ)一些小數(shù)據(jù)所以用的歸檔,希望對(duì)用歸檔存儲(chǔ)數(shù)據(jù)的同學(xué)有幫助。

iOS的幾種數(shù)據(jù)持久化方案

  • NSKeyedArchiver(歸檔)
  • preference(偏好設(shè)置)
  • plist文件
  • SQLite
  • CoreData

自定義類歸與解檔

1.需要實(shí)現(xiàn)<NSCoding>代理方法
2.需要實(shí)現(xiàn)的方法

- (instancetype)initWithCoder:(NSCoder *)coder
- (void) encodeWithCoder: (NSCoder *)coder

利用runtime獲得所有屬性

- (NSArray *)getAllProperty {
    NSMutableArray *array = [[NSMutableArray alloc]init];
    unsigned int *count = malloc(sizeof(unsigned int));
    //調(diào)用runtime方法
    //Ivar:方法返回的對(duì)象內(nèi)容對(duì)象,這里將返回一個(gè)Ivar類型的指針
    //class_copyIvarList 方法可以捕獲到類的所有變量 將變量的數(shù)量存在一個(gè) unsigned int指針中
    Ivar *mem = class_copyIvarList([self class], count);
    for (int i = 0; i < *count; i++) {
        //通過(guò)移動(dòng)指針進(jìn)行遍歷
        Ivar var = * (mem + i);
        //獲取變量的名稱
        const char *name = ivar_getName(var);
        NSString *varStr = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
        [array addObject:varStr];
    }
    //釋放內(nèi)存
    free(count);
    //注意處理野指針
    count = nil;
    return array;
}
  • initWithCoder
- (instancetype)initWithCoder:(NSCoder *)coder {
    if (self = [super init]) {
        //獲取所有屬性
        NSArray *porpertyArray = [self getAllProperty];
        for (NSString *name in porpertyArray) {
            //去掉屬性名前面的_
            NSString *key = [name substringFromIndex:1];
            //設(shè)置約定的鍵值對(duì) c+key
            [self setValue:[coder decodeObjectForKey:[NSString stringWithFormat:@"c%@",key]] forKey:key];
        }
    }
    return self;
}
  • encodeWithCoder
- (void)encodeWithCoder:(NSCoder *)coder {
    //獲取所有屬性
    NSArray *porpertyArray = [self getAllProperty];
    for (NSString *name in porpertyArray) {
        //去掉屬性名前面的_
        NSString *key = [name substringFromIndex:1];
        //設(shè)置約定的鍵值對(duì) c+key
        [coder encodeObject:[self valueForKey:key] forKey:[NSString stringWithFormat:@"c%@",key]];
    }
}

3.存儲(chǔ)數(shù)據(jù)

  • 自定義一個(gè)方法存儲(chǔ)數(shù)據(jù)
/**
 存儲(chǔ)數(shù)據(jù)

 @param OAuth 需要儲(chǔ)存的對(duì)象

 @return 是否儲(chǔ)存成功
 */
+ (BOOL)saveOAuth:(OAuth *)OAuth;
  • 方法實(shí)現(xiàn)
+ (BOOL)saveOAuth:(OAuth *)OAuth {
    //獲取doc的目錄
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    //拼接保存的路徑
    NSString *filePath = [docPath stringByAppendingPathComponent:oauthPath];
    //存儲(chǔ)返回用戶信息
    return [NSKeyedArchiver archiveRootObject:OAuth toFile:filePath];
}

4.獲取存儲(chǔ)對(duì)象

  • 自定義定義方法
/**
 @return 獲取存儲(chǔ)對(duì)象
 */
+ (OAuth *)OAuth;
  • 實(shí)現(xiàn)方法
+ (OAuth *)OAuth {
    //獲取doc的目錄
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    //拼接保存的路徑
    NSString *filePath = [docPath stringByAppendingPathComponent:oauthPath];
    //獲取用戶存儲(chǔ)的授權(quán)信息
    OAuth *oAuth = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    if (!oAuth) {
        oAuth = [[OAuth alloc]init];
    }
    return oAuth;
}

5.刪除所有歸檔

  • 自定義方法
/**
 刪除所有歸檔
 */
+ (void)logOut;
  • 實(shí)現(xiàn)方法
+ (void)logOut {
    //獲取doc的目錄
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    //拼接保存的路徑
    NSString *filePath = [docPath stringByAppendingPathComponent:oauthPath];
    //刪除路徑.data文件
    NSFileManager *fileManage = [NSFileManager defaultManager];
    [fileManage removeItemAtPath:filePath error:nil];
}

總結(jié)

以上是我用歸檔存儲(chǔ)數(shù)據(jù)的代碼。
github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容