數據存儲的三種方式

 
讀取info.plist文件:
 NSDictionary *infoDict =  [NSBundle mainBundle].infoDictionary;
 NSString *version = infoDict[@"CFBundleVersion"];
一,屬性列表
屬性列表即plist文件,實質是xml文件。 

注意點:json

    1. 根節點只能是NSArray或者NSDictionary 
    2. 若是對象是NSString、NSDictionary、NSArray、NSData、NSNumber等類型,就可使用writeToFile:atomically:方法直接將對象寫到屬性列表文件中
  • 將一個NSDictionary對象歸檔到一個plist屬性列表中
// 將數據封裝成字典
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"母雞" forKey:@"name"];
[dict setObject:@"15013141314" forKey:@"phone"];
[dict setObject:@"27" forKey:@"age"];
// 將字典持久化到Documents/stu.plist文件中
[dict writeToFile:path atomically:YES];
 
 
二,偏好設置
     用於保存APP的設置,例如是否記住密碼、是否接受推送、保存字體大小等。
// 保存數據
-(void)saveData
{
    // 1.獲取偏好設置
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

    // 2.保存數據
    [userDefaults setObject:@"傳智播客" forKey:@"itcastKey"];
    [userDefaults setBool:YES forKey:@"isGoodKey"];
 
/*注意:UserDefaults設置數據時,不是當即寫入,而是根據時間戳定時地把緩存中的數據寫入本地磁盤。因此調用了set方法以後數據有可能尚未寫入磁盤應用程序就終止了。出現以上問題,能夠經過調用synchornize方法強制寫入
*/ 
  // 3.同步數據(iOS8)
    [userDefaults synchronize];
}

// 讀取數據
-(void)readData
{
    // 1.獲取偏好設置
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

    // 2.讀取數據
    NSLog(@"%@",[userDefaults objectForKey:@"itcastKey"]);
}
 
 
三,歸檔能夠將 任意類型的對象,編碼後以 二進制的形式保存。
在使用plist進行數據存儲和讀取,只適用於系統自帶的一些經常使用類型才能用,且必須先獲取路徑相對麻煩;
偏好設置(將全部的東西都保存在同一個文件夾下面,且主要用於存儲應用的設置信息)
歸檔優點:由於前二者都有一個致命的缺陷,只能存儲經常使用的類型。歸檔能夠實現把自定義的對象存放在文件中。
 
注意點:
  1. 須要歸檔的自定義類,必須實現<NSCoding>協議,告訴系統須要歸檔和解檔哪些屬性。
  2. 若對象的屬性中有自定義類型,則該類也須要實現<NSCoding>協議。
// 保存數據
-(void)saveData
{
    // 1.建立對象
    CZPerson *person = [CZPerson new];
    person.name = @"Jack";
    person.age = 18;

    // 2.實現<NSCoding>協議

    // 3.獲取文件路徑
    NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *filePath = [documents stringByAppendingPathComponent:@"person.data"];

    // 4.編碼並保存(歸檔)
    [NSKeyedArchiver archiveRootObject:person toFile:filePath];
}

// 讀取數據
-(void)readData
{
    // 1.獲取文件路徑
    NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *filePath = [documents stringByAppendingPathComponent:@"person.data"];

    // 2.解檔
    CZPerson *person = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

    NSLog(@"%@",person.name);
}
 
 實現 <NSCoding>協議
  • encodeWithCoder何時調用:對象歸檔時候調用
 
  • encodeWithCoder做用:告訴系統對象裏的哪些屬性須要歸檔,怎麼去歸檔,根據一個key去歸檔,目的就是之後取的時候,也根據這個key去取數據。
// 編碼
-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeInteger:_age forKey:@"age"];
}
  • initWithCoder做用:告訴系統對象裏的哪些屬性須要解檔,怎麼去解檔,根據以前存儲的key去解檔
    • initWithCoder是一個初始化方法,須要先初始化父類的,可是不能調用[super initWithCoder:],由於父類NSObject沒有遵照NSCoding協議。
    3> initWithCoder何時須要調用[super initWithCoder:]
    • initWithCoder原理:只要解析 文件就會調用,xib,storyboard都是文件,所以只要解析這兩個文件,就會調用initWithCoder。
    • 所以若是在storyboard使用自定義view,重寫initWithCoder方法,必定要調用[super initWithCoder:],由於只有系統才知道怎麼解析storyboard,若是沒有調用,就解析不了這個文件。
// 解碼,實例化
-(instancetype)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init])
    {//將對象的一些屬性保存,沒有設置的屬性不做保存
        _name = [aDecoder decodeObjectForKey:@"name"];
        _age = [aDecoder decodeIntegerForKey:@"age"];
    }
    return self;
}
 

兩個方法的區別與使用場景
/// 解歸檔 : 這個方法是把視圖從bundle加載到內存.視圖的frame可能不許
//- (instancetype)initWithCoder:(NSCoder *)aDecoder
//{
//    if (self = [super initWithCoder:aDecoder]) {
//        NSLog(@"%s",__func__);
//    }
//    return self;
//}

/// 視圖被喚醒的方法.在這個方法裏面能夠拿到準確frame的視圖
- (void)awakeFromNib
{
 
}
 
//讀取JSON文件,轉模型
+ (NSArray *)projects {
    // 1. 文件路徑
    NSString *path = [[NSBundle mainBundle] pathForResource:@"more_project.json" ofType:nil];
    // 2. 讀取文件內容 -  二進制數據
    NSData *data = [NSData dataWithContentsOfFile:path];
    // 3. 解析JSON 專門用來解析JSON的類 NSJSONSerialization
    /**
     看到options先傳0.沒有達到效果再來看枚舉值
     */
    NSArray *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    // 聲明一個可變的數組
    NSMutableArray *projects = [NSMutableArray array];
    // 4. 遍歷數據,把字典轉成模型 - 使用block來遍歷數組
    [json enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        CZProject *project = [CZProject projectWithDict:obj];
        [projects addObject:project];
    }];
// 將可變數組,變成不可變 : 將線程不安全的類,變成了線程安全的類.同時,不可變的數組,外界不能修改的.
    return projects.copy;
}
相關文章
相關標籤/搜索