iOS開發(fā) - 關(guān)于 NSUserDefaults 的使用

####簡介:

  • NSUserDefaults是一個單例,在整個程序中只有一個實例對象,他可以用于數(shù)據(jù)的永久保存,而且簡單實用,這是它可以讓數(shù)據(jù)自由傳遞的一個前提。
  • NSUserDefaults適合 存儲輕量級 的本地數(shù)據(jù) ,比如要保存一個登陸界面的數(shù)據(jù),用戶名、密碼之類的,個人覺得使用NSUserDefaults是首選。下次再登陸的時候就可以直接從NSUserDefaults里面讀取上次登陸的信息。就像讀字符串一樣,直接讀取就可以了。
  • 用NSUserDefaults存儲的數(shù)據(jù)下次程序運(yùn)行的時候依然存在 .它的數(shù)據(jù)存儲在應(yīng)用程序內(nèi)置的一個plist文件里, 在/Library/Prefereces沙盒路徑下.

支持?jǐn)?shù)據(jù)格式:

NSNumber ( Integer、Float、Double )
NSString
NSArray
NSDictionary
BOOL類型
NSDate

簡單類型數(shù)據(jù)讀寫 NSUserDefaults 中:

  // 1. 創(chuàng)建NSUserDefaults單例:
  NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

  // 2. 數(shù)據(jù)寫入:
    // 通過 key 值 來存入 和 讀取數(shù)據(jù)
  [defaults setInteger:23 forKey:@"myInteger"];
    // 注意:對相同的Key賦值約等于一次覆蓋,要保證每一個Key的唯一性

  // 3. 將數(shù)據(jù) 立即存入到 磁盤:
  [defaults synchronize];

  // 4. 通過key值 按照寫入對應(yīng)類型 讀取數(shù)據(jù) 有返回值
  NSInteger *myInteger = [defaults integerForKey:@"myInteger"];

注意:

NSUserDefaults 存儲的對象全是不可變的(這一點非常關(guān)鍵,弄錯的話程序會出bug),例如,如果我想要存儲一個 NSMutableArray 對象,我必須先創(chuàng)建一個不可變數(shù)組(NSArray)再將它存入NSUserDefaults中去,代碼如下:

  NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"123",@"234", nil];
  NSArray * array = [NSArray arrayWithArray:mutableArray];
  NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
  [user setObject:array forKey:@"記住存放的一定是不可變的"];

取出數(shù)據(jù)是一樣的,想要用NSUserDefaults中的數(shù)據(jù)給可變數(shù)組賦值, 先給出一個錯誤的寫法:

  /*-------------------------錯誤的賦值方法-------------------*/
  NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
  //這樣寫后,mutableArray 就變成了不可變數(shù)組了,如果你要在數(shù)組中添加或刪除數(shù)據(jù)就會出現(xiàn)bug
  NSMutableArray *mutableArray = [user objectForKey:@"記住存放的一定是不可變的"];

正確的寫法:

  /*-------------------------正確的賦值方法-------------------*/
  NSUserDefaults *user = [NSUserDefaults standardUserDefaults];

  NSMutableArray *mutableArray = [NSMutableArray
arrayWithArray:[user objectForKey:@"記住存放的一定是不可變的"]];

將自定義類型數(shù)據(jù)讀寫 NSUserDefaults 中

使用NSKeyedArchiver 對數(shù)據(jù)進(jìn)行歸檔 反歸檔.

  • 將自定義類型轉(zhuǎn)換為NSData類型:

當(dāng)數(shù)據(jù)重復(fù)而且多的時候(例如想存儲全班同學(xué)的學(xué)號,姓名,性別(這個數(shù)據(jù)量可能太大了 )),如果不用SQLite 存儲 (多數(shù)據(jù)最好還是用這個),可以選擇使用歸檔,再將文件寫入本地,但是這種方式和 NSUserDefaults 比起來麻煩多了(因為NSFileManage 本來就挺復(fù)雜) ,但是問題是,NSUserDefaults 本身不支持自定義對象的存儲,不過它支持NSData的類型,可以轉(zhuǎn)化為 NSdata 類型 。

我們先建立一個叫Student 的類,這個類里有三個屬性(姓名, 年齡, 性別),代碼如下:

//  Created by LiCheng on 16/5/5.
//  Copyright ? 2016年 LiCheng. All rights reserved.
//
#import <Foundation/Foundation.h>

@interface Student : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *sex;
@property (nonatomic, assign) NSInteger age;

@end

我們要做的就是將Student類型變成NSData類型 ,那么就必須實現(xiàn)歸檔
這里要實現(xiàn) 在.h 文件中申明 NSCoding 協(xié)議,再 在 .m 中實現(xiàn) encodeWithCoder 方法 和
initWithCoder 方法就可以了 :
.h 中修改,代碼如下 :

#import <Foundation/Foundation.h>

@interface Student : NSObject  <NSCoding>

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *sex;
@property (nonatomic, assign) NSInteger age;

@end

.m中加入代碼 :

//  Created by LiCheng on 16/5/5.
//  Copyright ? 2016年 LiCheng. All rights reserved.
//
#import "Student.h"

@implementation Student
// 歸檔
-(void)encodeWithCoder:(NSCoder *)aCoder{
    
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeObject:self.age forKey:@"age"];
    [aCoder encodeObject:self.sex forKey:@"sex"];
}
// 反歸檔
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
    
    self = [super init];
    if (self) {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.age = [aDecoder decodeObjectForKey:@"age"];
        self.sex = [aDecoder decodeObjectForKey:@"sex"];
    }
    return self;
}
@end

這樣做就可以將自定義類型轉(zhuǎn)變?yōu)镹SData類型了, 下來進(jìn)行 寫入 和 讀取.

  • 寫入數(shù)據(jù):

如果要存儲全班同學(xué)的信息,我們可以建一個NSMutableArray 來存放全班同學(xué)的信息(里面存儲的全是NSData對象)在需要存儲的地方加入代碼:

    // 首先,要建立一個可變數(shù)組來存儲 NSDate對象
    Student *student = [[Student alloc] init];

    // 下面進(jìn)行的是對student對象的 name, age, sex 賦值
    student.name = @"張三";
    student.age = @"20";
    student.sex = @"男";
    
    // 將student對象轉(zhuǎn)換成為NSData類型
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:student];
    
    // 保存學(xué)生信息
    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
    [user setObject:data forKey:@"oneStudent"];

如果你想存儲全班同學(xué)的信息,你還要用一個for循環(huán)將data 放入 dataArray中.

  • 讀取數(shù)據(jù):

例如還原一個學(xué)生的數(shù)據(jù):

    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
    
    // 讀取data數(shù)據(jù)
    NSData *data = [user objectForKey:@"oneStudent"];
    
    // 將data類型轉(zhuǎn)換成student類型
    Student *student = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    NSLog(@"%@", student.name);
    NSLog(@"%@", student.age);
    NSLog(@"%@", student.sex);

總之,NSUserDefaults 在我們編寫代碼中是最常用的一個永久保存數(shù)據(jù)的方法,也是最簡單的。


GitHub: https://github.com/LiCheng244/LCUtils
個人博客: http://www.licheng244.com/


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

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

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