1、直接寫文件的方式,可以存儲的對象有NSString、NSArray、NSDictionary、NSData、NSNumber,數據全部存放在一個屬性列表文件(*.plist文件)中。
2、NSUeserDefaults(偏好設置),用來存儲應用設置信息,文件放在perference目錄下。
3、歸檔操作(NSkeyedArchiver),不同於前面兩種,它可以把自定義對象存放在文件中。
首先每個開發者都應該知道,對於一個應用來說,有唯一的沙盒與之對應,即每個應用不能跨沙盒操作文件。
直接來看代碼:
#import "ViewController.h"
@interface ViewController ()
@end
@implementationViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view,typically from a nib.
[self mainOperation];
}
- (void)mainOperation
{
//獲取沙盒中緩存文件夾路徑
//方法一
//沙盒主目錄
NSString *homePath = NSHomeDirectory();
//拼接路徑
NSString *path = [homePath stringByAppendingPathComponent:@"Library/Caches"];
//方法二
//第一個參數目標文件夾目錄(NSCachesDirectory查找緩存文件夾),第二個參數為查找目錄的域(NSUserDomainMask為在用戶目錄下查找),第三個參數為結果中主目錄是否展開,不展開則顯示為~
NSArray *arr = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
//雖然該方法返回的是一個數組,但是由於一個目標文件夾只有一個目錄,所以數組中只有一個元素。
NSString *cachePath = [arr lastObject];
//或者
// NSString *cachePath = [arr objectAtIndex:0];
/**
//獲取沙盒中Document文件夾或者tmp文件夾路徑都可使用上面兩種方法
//tmp文件夾路徑可直接這樣獲取
NSString *tmpPath = NSTemporaryDirectory();
NSLog(@"%@",tmpPath);
**/
//拼接路徑(目標路徑),這個時候如果目錄下不存在這個lotheve.plist文件,這個目錄實際上是不存在的。
NSString *filePath = [cachePath stringByAppendingPathComponent:@"tese.plist"];
NSLog(@"%@",filePath);
//創建數據
NSDictionary *content = @{@"字典數據測試1":@"1",@"字典數據測試2":@"2",@"字典數據測試":@"3"};
//將數據存到目標路徑的文件中(這個時候如果該路徑下文件不存在將會自動創建)
//用writeToFile方法寫文件會覆蓋掉原來的內容
[content writeToFile:filePath atomically:YES];
//讀取數據(通過字典的方式讀出文件中的內容)
NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:filePath];
NSLog(@"%@",dic);
}
@end
沙盒中Library/Caches目錄下多了lotheve.plist文件

文件內容:

每個應用都有一個NSUesrDefaults實例,通過它可以存儲應用配置信息以及用戶信息,比如保存用戶名、密碼、字體大小、是否自動登錄等等。數據自動保存在沙盒的Libarary/ Preferences目錄下。同樣,該方法只能存取NSString、NSArray、NSDictionary、NSData、NSNumber類型的數據。
代碼示例:
#import "LXXViewController.h"
@interface LXXViewController ()
@end
@implementationLXXViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"NSUserDefaults Demo";
}
//點擊button保存數據
- (IBAction)saveData:(id)sender {
//獲取NSUserDefaults對象
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//存數據,不需要設置路勁,NSUserDefaults將數據保存在preferences目錄下
[userDefaults setObject:@"Lotheve" forKey:@"name"];
[userDefaults setObject:@"NSUserDefaults" forKey:@"demo"];
//立刻保存(同步)數據(如果不寫這句話,會在將來某個時間點自動將數據保存在preferences目錄下)
[userDefaults synchronize];
NSLog(@"數據已保存");
}
//點擊button讀取數據
- (IBAction)getData:(id)sender
{
//獲取NSUserDefaults對象
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//讀取數據
NSString *name = [userDefaults objectForKey:@"name"];
NSString *demo = [userDefaults objectForKey:@"demo"];
//打印數據
NSLog(@"name = %@ demo =%@",name,demo);
}
@end
Interface Building中設置了兩個按鈕:

點擊“保存數據”後,查看沙盒中的Libarary/ Preferences目錄:

數據以plist的格式寫入磁盤中了。點開查看數據:

使用歸檔操作存儲數據的主要好處是,不同於前面兩種方法只能存儲幾個常用的數據類型的數據,NSKeyedArchiver可以存儲自定義的對象。
代碼示例:
需要注意的是,需要保存的對象類一定要引用NSCoding協議,並且實現
- (void)encodeWithCoder:(NSCoder *)aCoder - (id)initWithCoder:(NSCoder *)aDecoder
1、文件結構:

2、代碼示例:
LXXViewController.m
#import "LXXViewController.h"
#import "TestPerson.h"
@interface LXXViewController ()
@property (nonatomic ,strong) TestPerson *p;
@end
@implementationLXXViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (IBAction)saveData:(id)sender
{
//創建一個自定義類的實例
_p = [[TestPerson alloc]init];
_p.name = @"Lotheve";
_p.age = 20;
_p.sex = @"m";
_p.familyMumbers = @[@"Father",@"Mather",@"Me"];
//獲取文件路徑
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
//文件類型可以隨便取,不一定要正確的格式
NSString *targetPath = [docPath stringByAppendingPathComponent:@"lotheve.plist"];
//將自定義對象保存在指定路徑下
[NSKeyedArchiver archiveRootObject:_p toFile:targetPath];
NSLog(@"文件已儲存");
}
- (IBAction)getData:(id)sender
{
//獲取文件路徑
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *targetPath = [docPath stringByAppendingPathComponent:@"lotheve.plist"];
TestPerson *person = [NSKeyedUnarchiver unarchiveObjectWithFile:targetPath];
NSLog(@"name = %@ , age =%ld , sex = %@ , familyMubers = %@",person.name,person.age,person.sex,person.familyMumbers);
NSLog(@"文件已提取");
}
@end
TestPerson.h
#import@interface TestPerson : UIViewController @property (nonatomic, copy) NSString *name; @property (nonatomic, assign) NSInteger age; @property (nonatomic, copy) NSString *sex; @property (nonatomic, strong) NSArray *familyMumbers; @end
TestPerson.m
#import "TestPerson.h"
@interface TestPerson ()
@end
@implementationTestPerson
- (void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark - NSCoding協議方法 (一定要實現)
//當進行歸檔操作的時候就會調用該方法
//在該方法中要寫清楚要存儲對象的哪些屬性
- (void)encodeWithCoder:(NSCoder *)aCoder
{
NSLog(@"調用了encodeWithCoder方法");
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeInteger:_age forKey:@"age"];
[aCoder encodeObject:_sex forKey:@"sex"];
[aCoder encodeObject:_familyMumbers forKey:@"familyMumbers"];
}
//當進行解檔操作的時候就會調用該方法
//在該方法中要寫清楚要提取對象的哪些屬性
- (id)initWithCoder:(NSCoder *)aDecoder
{
NSLog(@"調用了initWithCoder方法");
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
self.sex = [aDecoder decodeObjectForKey:@"sex"];
_familyMumbers = [aDecoder decodeObjectForKey:@"familyMumbers"];
}
return self;
}
@end
點擊“保存數據”後,查看沙盒中Documents目錄:

點擊查看文件內容:

點擊“提取數據”後打印結果:
