一 沙盒
NSString *path = NSHomeDirectory();
上面的代碼是應(yīng)用程序目錄的路徑,在該目錄下有三個(gè)文件夾: Documents, library, temp 以及一個(gè).app 包,該目錄下就是應(yīng)用程序的沙盒,
應(yīng)用程序只能訪問(wèn)該目錄下的文件夾
1./Documents: 保存應(yīng)用程序的重要數(shù)據(jù)文件和用戶(hù)數(shù)據(jù)文件等, 該路徑可通過(guò)配置實(shí)現(xiàn) iTunes 共享文件,可被 iTunes 備份
2.Liberary 目錄下有兩個(gè)子目錄:
/Preferences 目錄: 包含了應(yīng)用程序的偏好設(shè)置文件,不應(yīng)該直接創(chuàng)建偏好設(shè)置文件,應(yīng)該使用 NSUserDefaults 類(lèi)來(lái)取得和設(shè)置應(yīng)用程序的偏好
/Caches 目錄: 保存應(yīng)用程序使用時(shí)產(chǎn)生的支持文件和緩存文件,還有日志文件最好也在這個(gè)目錄下面,iTunes 同步不會(huì)備份該目錄,應(yīng)用程序如果有清除緩存功能清除的也是這個(gè)文件夾的內(nèi)容
3./tmp 保存應(yīng)用運(yùn)行時(shí)所需要的臨時(shí)數(shù)據(jù), iPhone 重啟時(shí),會(huì)清除該目錄下的所有文件
獲取沙盒各個(gè)文件夾路徑
1.沙盒根目錄
NSLog(@"%@", NSHomeDirectory());
2.MyApp.app
應(yīng)用程序包: 存放的是應(yīng)用程序的源文件: 資源文件和可執(zhí)行文件
NSLog(@“%@“, [[NSBundle mainBundle] bundlePath]);
3./Documents
// 參數(shù)1: 要查找的目錄
// 參數(shù)2: 是否是用戶(hù)主目錄
// 參數(shù)3: YES/NO 是否獲取全路徑
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentpath = paths.lastObject;
NSLog(@"documentpath---%@", documentpath);
4./Library
NSArray *paths2 = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *library = paths2.lastObject;
NSLog(@"library---%@", library);
5./Library/caches
NSArray *patchs3 = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesPath = patchs3.lastObject;
NSLog(@"cachesPath---%@", cachesPath);
6./Library/Preference
// Preferences,只能用拼接的方式找到
// preferencePanes iphone 沒(méi)有這個(gè)目錄
NSArray * paths4 = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); NSString * preferencePath = [[paths4 lastObject] stringByAppendingPathComponent:@"Preferences"]; NSLog(@"%@", preferencePath);
7./Tmp
NSArray * paths4 = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES); NSString * preferencePath = [[paths4 lastObject] stringByAppendingPathComponent:@"Preferences"]; NSLog(@"%@", preferencePath);
二 plist 文件
plist 的全名是: Property List, 屬性列表文件, 它是一種存儲(chǔ)串行化后的對(duì)象的文件。屬性列表文件的擴(kuò)展名為. plist, 因此通常被稱(chēng)為 plist 文件
plist 保存的地方
1.工程的沙盒里 (就是程序 user Document文件夾下,用代碼創(chuàng)建,可以讀取數(shù)據(jù),寫(xiě)入數(shù)據(jù))
2.工程自身里 (使用Xcode手動(dòng)創(chuàng)建一個(gè). plist 文件,數(shù)據(jù)需要手工寫(xiě)入)
3.工程沙盒里 (保存到 user Document 下,使用NSUserdefault
可以快速保存添加讀取刪除基本數(shù)據(jù)類(lèi)型)
plist 文件是通過(guò) XML 文件的方式保存在目錄中, 以下類(lèi)型可以被序列化:
NSString;//字符串
NSMutableString;//可變字符串
NSArray;//數(shù)組
NSMutableArray;//可變數(shù)組
NSDictionary;//字典
NSMutableDictionary;//可變字典
NSData;//二進(jìn)制數(shù)據(jù)
NSMutableData;//可變二進(jìn)制數(shù)據(jù)
NSNumber;//基本數(shù)據(jù)
NSDate;//日期
從手工創(chuàng)建Plist 文件的數(shù)據(jù)讀取
// testPlist 是你用 Xcode 創(chuàng)建的 plist 文件的文件名
NSString *plistPath = [[NSBundle mainBundle]pathForResource:@"PropertyListTest" ofType:@"plist"];
NSMutableDictionary *dataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:plistPath];
NSLog(@"%@",dataDic);//直接打印數(shù)據(jù)
代碼創(chuàng)建 Plist 文件 以及相關(guān)操作
- (void)getDataFromPlist{
//沙盒獲取路徑
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [pathArray objectAtIndex:0];
//獲取文件的完整路徑
NSString *filePatch = [path stringByAppendingPathComponent:@"PropertyListTest.plist"];//沒(méi)有會(huì)自動(dòng)創(chuàng)建
NSLog(@"file patch%@",filePatch);
NSMutableDictionary *sandBoxDataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:filePatch];
if (sandBoxDataDic==nil) {
sandBoxDataDic = [NSMutableDictionary new];
sandBoxDataDic[@"test"] = @"test";
[sandBoxDataDic writeToFile:filePatch atomically:YES];
}
NSLog(@"sandBox %@",sandBoxDataDic);//直接打印數(shù)據(jù)
}
- (void)writeDataToPlist{
//這里使用位于沙盒的plist(程序會(huì)自動(dòng)新建的那一個(gè))
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [pathArray objectAtIndex:0];
//獲取文件的完整路徑
NSString *filePatch = [path stringByAppendingPathComponent:@"PropertyListTest.plist"];
NSMutableDictionary *sandBoxDataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:filePatch];
NSLog(@"old sandBox is %@",sandBoxDataDic);
sandBoxDataDic[@"test"] = @"hello world";
[sandBoxDataDic writeToFile:filePatch atomically:YES];
sandBoxDataDic = [[NSMutableDictionary alloc]initWithContentsOfFile:filePatch];
NSLog(@"new sandBox is %@",sandBoxDataDic);
三 preference 偏好設(shè)置
使用NSUserdefaults
來(lái)進(jìn)行偏好設(shè)置,例如設(shè)置一些默認(rèn)背景色,圖片,常用信息等
-
NSUserdefaults
是一個(gè)單例,在整個(gè) app 中都可以使用,同時(shí)也是線(xiàn)程安全的,NSUserdefaults
存儲(chǔ)的本質(zhì)就是一個(gè) Plist 文件 -
NSUserdefaults
存儲(chǔ)的位置在沙盒目錄下的/ Library/Preferences - plist文件可以存儲(chǔ)的數(shù)據(jù)類(lèi)型
NSUserdefaults
都可以存儲(chǔ) -
NSUserdefaults
為了避免每次讀取數(shù)據(jù)時(shí)都打開(kāi)用戶(hù)默認(rèn)數(shù)據(jù)的操作,所以調(diào)用set
方法后不會(huì)立即寫(xiě)入,而是根據(jù)時(shí)間戳定時(shí)把緩存中的數(shù)據(jù)寫(xiě)入本地磁盤(pán),所有有可能調(diào)用了set
方法后數(shù)據(jù)還沒(méi)來(lái)得及寫(xiě)入磁盤(pán)應(yīng)用程序就終止了,可以使用synchornize
方法強(qiáng)制寫(xiě)入 - 從
NSUserdefaults
返回的值是不可變的,即便你存儲(chǔ)的時(shí)候使用的是可變的值
獲得 NSUserdefaults 的對(duì)象
+ (NSUserDefaults *)standardUserDefaults;
存儲(chǔ)數(shù)據(jù)
- (void)setObject:(nullable id)value forKey:(NSString *)defaultName;
- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName;
- (void)setFloat:(float)value forKey:(NSString *)defaultName;
- (void)setDouble:(double)value forKey:(NSString *)defaultName;
- (void)setBool:(BOOL)value forKey:(NSString *)defaultName;
- (void)setURL:(nullable NSURL *)url forKey:(NSString *)defaultName NS_AVAILABLE(10_6, 4_0);
讀取數(shù)據(jù)
- (nullable id)objectForKey:(NSString *)defaultName;
- (nullable NSString *)stringForKey:(NSString *)defaultName;
- (nullable NSArray *)arrayForKey:(NSString *)defaultName;
- (nullable NSDictionary<NSString *, id> *)dictionaryForKey:(NSString *)defaultName;
- (nullable NSData *)dataForKey:(NSString *)defaultName;
- (nullable NSArray<NSString *> *)stringArrayForKey:(NSString *)defaultName;
- (NSInteger)integerForKey:(NSString *)defaultName;
- (float)floatForKey:(NSString *)defaultName;
- (double)doubleForKey:(NSString *)defaultName;
- (BOOL)boolForKey:(NSString *)defaultName;
- (nullable NSURL *)URLForKey:(NSString *)defaultName NS_AVAILABLE(10_6, 4_0);
移除數(shù)據(jù)
- (void)removeObjectForKey:(NSString *)defaultName;
同步數(shù)據(jù)
- (BOOL)synchronize;
NSKeyedArchiver 歸檔 解歸檔
歸檔(序列化)
是把對(duì)象轉(zhuǎn)為字節(jié)碼,以文件的形式存儲(chǔ)到磁盤(pán)上;程序運(yùn)行過(guò)程中或者再次重新打開(kāi)程序的時(shí)候,可以通過(guò)解歸檔(反序列化)
還原這些對(duì)象,歸檔
和解歸檔
用于少量數(shù)據(jù)的持久化存儲(chǔ)和讀取
歸檔之后的文件存儲(chǔ)在/ Documents 目錄下
在 iOS中,只要遵循了NSCoding 協(xié)議
的對(duì)象都可以通過(guò)它來(lái)實(shí)現(xiàn)序列化
NSCoding 協(xié)議
有2個(gè)方法是必須實(shí)現(xiàn)的:
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (instancetype)initWithCoder:(NSCoder *)aDecoder
使用示例
.h 文件
#import <Foundation/Foundation.h>
@interface Student : NSObject<NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *sex;
@property (nonatomic, assign) NSUInteger height;
@end
.m 文件
#import "Student.h"
@implementation Student
// 歸檔
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.sex forKey:@"sex"];
[aCoder encodeInteger:self.height forKey:@"height"];
}
// 解檔
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.sex = [aDecoder decodeObjectForKey:@"sex"];
self.height = [aDecoder decodeIntegerForKey:@"height"];
}
return self;
}
@end
viewController (或其他地方)里面的使用:
// 歸檔
- (void)archiver{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask , true);
NSString *documentPath = paths.lastObject;
NSString *filePath = [documentPath stringByAppendingPathComponent:@"test.data"];
Student *student = [[Student alloc] init];
student.name = @"cc";
student.sex = @"女";
student.height = 170;
[NSKeyedArchiver archiveRootObject:student toFile:filePath];
}
// 解檔
- (void)unArchiver
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true);
NSString *documentPath = paths.lastObject;
NSString *filePath = [documentPath stringByAppendingPathComponent:@"test.data"];
Student *student = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
if (student) {
NSLog(@"名字:%@ 性別:%@ 身高:%lu", student.name, student.sex, student.height);
}
}