iOS數據持久化(一)

1、什麼是數據持久化ios

數據持久化及數據的永久存儲,將數據保存在硬盤中,程序關閉,內存釋放後,從新打開程序,能夠繼續訪問以前保存的數據。數組

2、數據持久化方式緩存

常見的數據持久化方式有如下幾項:安全

沙盒多線程

preferenceapp

歸檔 / 反歸檔工具

SQLite編碼

CoreDataatom

這篇只講沙盒,preference,歸檔/反歸檔。spa

1.沙盒

沙盒是系統爲每個應用程序生成的一個特定文件夾   文件夾的名字由十六進制數據組成,每個應用程序的沙盒文件名都是不同的,是由系統隨機生成的。

    //獲取沙盒主目錄
    NSString *path = NSHomeDirectory();
    NSLog(@"%@",path);

沙盒下每一個文件夾的路徑及做用

//Documents  存放的一些比較重要的文件,可是存入Documents中的文件不能過大
    //如何獲取Documents文件目錄
    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSLog(@"%@",documentsPath);
    //用firstobject取值是由於該方法一開始使用mac端OS X開發,對於PC端用戶能夠有多個用戶,因此能夠取到不少user的路徑,可是該方法如今用於手機開發,手機端只有一個用戶,因此得到的用戶只有一個,lastobject也是能夠的。
    
    //Library:是一個資源庫,存儲一些不過重要的數據,相對比較大一些,裏邊有兩個子文件夾;
    NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)firstObject];
    //Caches:緩存文件,圖片緩存,音頻,視頻。網頁資源。應用程序清除緩存,就是清除該文件夾
    NSString *cachesPath  = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)firstObject];
    //Preferences:系統偏好設置,用戶對應程序的設置,好比用戶名和用戶密碼,preference路徑沒法找到,經過NSUserDefaults
    
    //temp:存放臨時文件,好比下載的壓縮包zip,解壓後理解把壓縮包刪除
    NSString *tempPath = NSTemporaryDirectory();
    NSLog(@"%@",tempPath);
    //bundle:ios8以前,包和沙河在同一個目錄下,以後.app單獨存儲到一個獨立的文件目錄下。 .app 文件 readOnly。從appStore下載下來的是這個包,程序上傳的時候也是這個包
    NSString *bundlepath = [[NSBundle mainBundle] bundlePath];
    NSLog(@"%@",bundlepath);
    // NSSearchPathDirectory 這個類是用來查找文件目錄的
    //第一個參數:文件名稱
    //第二個參數,肯定搜索域
    //第三個參數:肯定相對路徑仍是絕對路徑。YES絕對,NO相對

文件相關操做

/**
 *  文件刪除
 */
- (void)deleteFile {
    NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];

     NSString *imagePath = [cachesPath stringByAppendingPathComponent:@"iamge"];
    NSLog(@"%@",imagePath);
    //建立文件管理者
    NSFileManager *fileManager =  [NSFileManager defaultManager];
    //判斷文件是否存在
    BOOL isExist = [fileManager fileExistsAtPath:imagePath];
    if (!isExist) {
        BOOL isSuccess = [fileManager createDirectoryAtPath:imagePath withIntermediateDirectories:YES attributes:nil error:nil];
        NSLog(@"%@",isSuccess ? @"建立成功" : @"建立失敗");
    }
    //刪除文件
    if ([fileManager fileExistsAtPath:imagePath]) {
        BOOL isSucess = [fileManager removeItemAtPath:imagePath error:nil];
        NSLog(@"%@",isSucess ? @"刪除成功" : @"刪除失敗");
    }
}
/**
 *  移動
 */
- (void)moveFile {
    NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    
    NSString *imagePath = [cachesPath stringByAppendingPathComponent:@"iamge"];
    NSLog(@"%@",imagePath);
    //建立文件管理者
    NSFileManager *fileManager =  [NSFileManager defaultManager];
    //判斷文件是否存在
    BOOL isExist = [fileManager fileExistsAtPath:imagePath];
    if (!isExist) {
        BOOL isSuccess = [fileManager createDirectoryAtPath:imagePath withIntermediateDirectories:YES attributes:nil error:nil];
        NSLog(@"%@",isSuccess ? @"建立成功" : @"建立失敗");
    }
    //刪除文件
    //    if ([fileManager fileExistsAtPath:imagePath]) {
    //        BOOL isSucess = [fileManager removeItemAtPath:imagePath error:nil];
    //        NSLog(@"%@",isSucess ? @"刪除成功" : @"刪除失敗");
    //    }
    //拷貝文件
    //    把包中的plist文件拷貝到image文件夾下
    NSString *plistInBundlePath = [[NSBundle mainBundle] pathForResource:@"NB.plist" ofType:nil];
    
    NSString *nBPath = [imagePath stringByAppendingPathComponent:@"NB.plist"];
    // 拷貝,
    if (![fileManager fileExistsAtPath:nBPath]) {
        BOOL isSuccess = [fileManager copyItemAtPath:plistInBundlePath toPath:nBPath error:nil];
        NSLog(@"%@",isSuccess ? @"拷貝成功" : @"拷貝失敗");
    }
    
    NSString *toPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject];
    BOOL isSuccess = [fileManager moveItemAtPath:nBPath toPath:[toPath stringByAppendingPathComponent:@"NB.plist"] error:nil];
    NSLog(@"%@",isSuccess ? @"移動成功" : @"移動失敗");
    
}
//字符串寫入文件
- (void)writeToFile {
    //簡單對象寫入文件:字符串,數組,字典,二進制流 只有這些簡單對象支持文件的寫入
    //若是要寫入的文件數據時數組,字典,必需要保證數組,字典中的數據 也是簡單對象(若是是複雜對象,請參照後邊的歸檔,反歸檔)
    //將字符串寫入Documents文件夾下
    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject];
    NSString *toPath = [documentsPath stringByAppendingPathComponent:@"string.txt"];
    NSString *string = @"string-string-string-";
    //第一個參數,要寫入的文件路徑,若是不存在文件,會自動建立    第二個參數,原子性,判斷是否須要生成輔助文件,保護在多線程下安全    第三個參數,編碼格式    第四個參數,錯誤信息
    NSError *error = nil;
    BOOL isSuccess = [string writeToFile:toPath atomically:YES encoding:NSUTF8StringEncoding error:&error];
    NSLog(@"%@",isSuccess ? @"寫入成功" : @"寫入失敗");
    
    NSString *str = [NSString stringWithContentsOfFile:toPath encoding:NSUTF8StringEncoding error:nil];
    NSLog(@"%@",str);
}
//數組寫入文件
- (void)writeArray {
    
    NSString *str = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)firstObject];
    NSString *toPath = [str stringByAppendingPathComponent:@"array.txt"];
    NSArray *array = @[@"123",@"123"];
    BOOL isSuccess = [array writeToFile:toPath atomically:YES];
    NSLog(@"%@",isSuccess ? @"寫入成功" : @"寫入失敗");
    
    NSArray *arr = [NSArray arrayWithContentsOfFile:toPath];
    NSLog(@"%@",arr);

}
//字典寫入文件
- (void)writeDic {
    NSDictionary *dic = @{@"key":@"value"};
    NSString *str = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)firstObject];
    NSString *toPath = [str stringByAppendingPathComponent:@"dictonry.txt"];
    BOOL isSuccess = [dic writeToFile:toPath atomically:YES];
    NSLog(@"%@",isSuccess ? @"成功" : @"失敗");
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:toPath];
    NSLog(@"%@",dict);
}
//NSData寫入文件
- (void)writeData {
    NSString *tempPath = NSTemporaryDirectory();
    NSString *toPath = [tempPath stringByAppendingPathComponent:@"data.txt"];
    NSString *string = @"datadata";
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    BOOL isSuccess = [data writeToFile:toPath atomically:YES];
    NSLog(@"%@",isSuccess ? @"成功" : @"失敗");
    NSData *getData = [NSData dataWithContentsOfFile:toPath];
    NSString *str = [[NSString alloc] initWithData:getData encoding:NSUTF8StringEncoding];
    NSLog(@"%@",str);
}

2.preference

//Preference
- (void)writeToPreference {
    // NSUserDefaults 繼承自NSObject ,單例     經過kvc模式賦值
    NSLog(@"%@",NSHomeDirectory());
    //建立用戶索引對象
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setInteger:100 forKey:@"money"];
    //當即同步操做      對preference中的文件進行修改後,當即同步
    [defaults synchronize];
    NSInteger money = [defaults integerForKey:@"money"];
    NSLog(@"%ld",money);
    [defaults setInteger:10000 forKey:@"MyMoney"];
    [defaults synchronize];
    
    NSInteger you = [defaults integerForKey:@"you"];
    NSLog(@"%ld",(long)you);
    if (money < 10) {
        NSLog(@"there is no money");
    } else {
        NSLog(@"-100");
        money -= 100;
        [defaults setInteger:40 forKey:@"money"];
        [defaults setInteger:1000 forKey:@"YourMoney"];
    }
    // NSUserDefaults 通常存儲一些比較小的數據,大部分用來存數值
    
    //例子:判斷用戶是否第一次登錄
    NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
    BOOL isFirst = [userDefault boolForKey:@"isFirst"];
    [userDefault setBool:YES forKey:@"isFirst"];
    [userDefault synchronize];
    if (!isFirst) {
        NSLog(@"第一次登錄");
    } else {
        NSLog(@"不是第一次登錄");
    }
}

3.歸檔 / 反歸檔

複雜對象寫入文件須要使用歸檔 ,讀取須要使用反歸檔,不能直接寫入文件,數組中有複雜對象也要使用歸檔 / 反歸檔

複雜對象使用行歸檔和反歸檔,須要遵循NSCoding協議,並實現協議中- (void)encodeWithCoder:(NSCoder *)aCoder;   - (id)initWithCoder:(NSCoder *)aDecoder; 兩個方法

 

新建Person類

在Person.h中 遵循協議

//
//  Person.h
//  07.24-DataPersistiser
//
//  Created by lanouhn on 14/7/24.
//  Copyright (c) 2014年 LCD. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Person : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *gender;
@property (nonatomic, assign) NSInteger age;
@end

在Person.m中實現協議方法

//
//  Person.m
//  07.24-DataPersistiser
//
//  Created by lanouhn on 14/7/24.
//  Copyright (c) 2014年 LCD. All rights reserved.
//

#import "Person.h"

@implementation Person

//當要歸檔時,對象會自動觸發這個方法
- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.gender forKey:@"gender"];
    [aCoder encodeObject:@(self.age) forKey:@"age"];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.gender = [aDecoder decodeObjectForKey:@"gender"];
        self.age = [[aDecoder decodeObjectForKey:@"age"] integerValue];
    }
    return self;
}
@end

歸檔 / 反歸檔

- (void)archiver {
    
    //把複雜文件寫入文件,先轉化爲nsdata對象
    //歸檔:歸檔的實質就是把其餘類型的數據(person),先轉化爲NSData,再寫入文件。
    Person *person = [[Person alloc] initWithName:@"rose" gender:@"girl" age:25];
    //    NSKeyedArchiver  壓縮工具類,繼承自NSCoder,主要用於編碼
    NSMutableData *data = [NSMutableData data] ;
    NSKeyedArchiver *achiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    //使用壓縮工具講Person壓到data中
    [achiver encodeObject:person forKey:@"person"];
    //完成壓縮,停掉壓縮工具
    [achiver finishEncoding];

    
    NSString *homePath = NSHomeDirectory();
    NSString *toPath = [homePath stringByAppendingPathComponent:@"person.txt"];
    BOOL isSuccess = [data writeToFile:toPath atomically:YES];
    NSLog(@"%@",isSuccess ? @"成功" : @"失敗");
    
    //複雜對象的讀取,反歸檔
    //    NSKeyedUnarchiver
    NSData *getData = [NSData dataWithContentsOfFile:toPath];
    NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:getData];
    //解壓
    Person *p1 = [unArchiver decodeObjectForKey:@"person"];
    [unArchiver finishDecoding];
}
 //集合NSArray NSDictionary 若是想進行歸檔和反歸檔,那麼它裏邊存儲的元素也要遵循NSCoding協議
    Person *person1 = [[Person alloc] initWithName:@"jack" gender:@"" age:20];
    Person *person2 = [[Person alloc] initWithName:@"rose" gender:@"" age:20];
    NSArray *array = @[person1,person2];

    
    NSMutableData *data = [NSMutableData data];
    
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:array forKey:@"array"];
    [archiver finishEncoding];

    
    NSString *tmpPath = NSTemporaryDirectory();
    NSString *toPath = [tmpPath stringByAppendingString:@"array.txt"];
    
    BOOL isSuccess = [data writeToFile:toPath atomically:YES];
    NSLog(@"%@",isSuccess ? @"成功" : @"失敗");
    //反歸檔
    NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    NSArray *unArchiverArray = [unArchiver decodeObjectForKey:@"array"];
相關文章
相關標籤/搜索