讀取info.plist文件:
NSDictionary *infoDict = [NSBundle mainBundle].infoDictionary;
NSString *version = infoDict[@"CFBundleVersion"];
一,屬性列表
屬性列表即plist文件,實質是xml文件。
注意點:json
-
- 根節點只能是NSArray或者NSDictionary
- 若是對象是NSString、NSDictionary、NSArray、NSData、NSNumber等類型,就可使用writeToFile:atomically:方法直接將對象寫到屬性列表文件中
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進行數據存儲和讀取,只適用於系統自帶的一些經常使用類型才能用,且必須先獲取路徑相對麻煩;
偏好設置(將全部的東西都保存在同一個文件夾下面,且主要用於存儲應用的設置信息)
歸檔優點:由於前二者都有一個致命的缺陷,只能存儲經常使用的類型。歸檔能夠實現把自定義的對象存放在文件中。
- 須要歸檔的自定義類,必須實現
<NSCoding>
協議,告訴系統須要歸檔和解檔哪些屬性。
- 若對象的屬性中有自定義類型,則該類也須要實現
<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;
}