編輯:關於Android編程
1.為什麼要進行數據持久化?
我們平時的浏覽記錄,qq的聊天記錄,收藏夾等,每次打開程序的視乎都會存在,理論上每次關閉應用的時候,程序中使用的數據資源都應該被釋放,將程序運行過程中或運行結束後的某些信息持久的保存起來就是數據持久化。
2:什麼是數據持久化
將數據模型轉換成存儲模型(內存中某些對象保存到磁盤中)
3:數據持久化的優點
就是將數據持久話的保存起來,不會丟失
4.數據持久化的方式:
①:文件
② plist文件:屬性列表文件,相當於一個小型數據庫,持久話一些比較小的數據,xml格式,持久話數組和字典對象
③歸檔和反歸檔:將內存中的對象保存在磁盤中
④NSUserDefaults: 持久化標簽(UI)
⑤數據庫:FMDB:對sqlite封裝, coredata: 數據庫的基礎上封裝了一層面向對象的思想 第三方庫
**
PList
**
1:什麼是plist文件
plist全稱:property List 屬性列表文件,plist是一個xml格式文件,後綴為.plist,只能持久化NSArray和NADictionary類型對象
2:plist文件的作用
作用:plist是做數據持久化的專業文件,.plist一般情況下用於存儲用戶密碼、臨時信息、簡介這樣的簡單的信息
3:Plist文件特點(先將Xcode創建plist文件,通過創建好的plist文件介紹plist文件特點)
a:plist文件的根路徑(root)是數組或字典類型(plist文件只能持久化數組或字典對象)
b:plist文件的自路徑只能是NSString NSNumber NSDate NSData NSArray NSDictionary類型的對象
4:Xcode創建plist文件
Plist文件內容的格式是xml語法格式
創建步驟
①.點擊File–》New File 彈出一對話框
②.iOS程序選中iOS欄中的Resource/Mac程序選中OS X 欄中的resource
③.點擊Resource中的Property List 創建plist文件
④.點擊文件中的’+’可以添加數據
5:代碼創建和讀取plist文件
如果想把NSString NSNumber NSDate NSData NSArray NSDictionary類的對象寫入文件中一般用plist文件,但是因為plist文件根路徑只能是NSArray和NSDoctionary所以只能持久化NSArray和NSDoctionary對象,這時候就需要將數據保存在數組或字典中然後調用數組和字典的相關方法把數組和字典寫入到plist文件中
//將數組和字典寫入plist文件的方法
//path:plist文件的路徑
//useAuxiliaryFile:是否具有原子性
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
//將plist文件讀取到數組和字典中
//將plist文件讀取到數組中(類方法)
+(id)arrayWithContentsOfFile:(NSString *)path;
//將plist文件讀取到字典中(類方法)
+(id)dictionaryWithContentsOfFile:(NSString *)path
例:
/*
//將數組寫入到plist文件中
例子1:創建一個數組,數組成員是NSString類型的對象@“ni”,@“hao”,@“ma”
把該數組持久化到一個plist文件中,並讀取plist文件中內容
*/
void arrayToPList1(void){
NSString *pathDesktop = @"/Users/mac/Desktop";
NSArray *array = [NSArray arrayWithObjects:@"bei", @"ni", @"hao", @"ma", nil];
//- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
//將數組寫入到plist文件
[array writeToFile:[pathDesktop stringByAppendingString:@"/arrayPlist1.plist"] atomically:YES];
//+ (id /* NSArray * */)arrayWithContentsOfFile:(NSString *)path;
//作用:將plist文件中的數據讀到數組中
NSArray *arrayFromPList = [NSArray arrayWithContentsOfFile:[pathDesktop stringByAppendingString:@"/arrayPlist1.plist"]];
NSLog(@"%@", arrayFromPList);
**
歸檔和反歸檔
**
1:什麼是歸檔和反歸檔
歸檔:歸檔就是通過某種格式把內存中的某個對象保存到本地文件中,以便以後再從該文件中讀回該對象
反歸檔:把歸檔的對象文件讀成原來的內存中的對象
2.如何歸檔和反歸檔
//歸檔
+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;
//反歸檔
+ (id)unarchiveObjectWithFile:(NSString *)path;
a. 系統類的歸檔和反歸檔
例:
//array的歸檔和反歸檔
void stringArchiverAndUnarchiver(void){
NSString *pathDesktop = @"/Users/mac/Desktop";//桌面路徑
NSArray *array = @[@"nihao",@"iOS"];
//+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;
//作用:系統類對象進行歸檔
BOOL success = [NSKeyedArchiver archiveRootObject:array toFile:[pathDesktop stringByAppendingString:@"/string歸檔文件"]];
if (success){
NSLog(@"歸檔成功");
}else{
NSLog(@"歸檔失敗");
}
//+ (id)unarchiveObjectWithFile:(NSString *)path;
//作用:歸檔文件的反歸檔
NSString *stringFromFile = [NSKeyedUnarchiver unarchiveObjectWithFile:[pathDesktop stringByAppendingString:@"/string歸檔文件"]];
NSLog(@"%@", stringFromFile);
注:對於系統類NSString和NSArray和NSDictionary對象都可以直接進行歸檔和反歸檔操作
b.自定義類的歸檔和反歸檔
對於系統類NSString和NSArray和NSDictionary對象可以直接進行歸檔和反歸檔操作,是不是說所有的類的對象都能進行歸檔和反歸檔
只有遵守了協議的類的對象才能進行歸檔和反歸檔操作
如果自定義的類對象要進行歸檔那麼這個對象的屬性所屬的類也必須要遵守歸檔協議NSCoding
必須實現以下兩個方法:
//歸檔的時候調用的方法
- (void)encodeWithCoder:(NSCoder *)aCoder;
//解歸檔的時候要調用的函數
- (id)initWithCoder:(NSCoder *)aDecoder;
例子:創建一個Student類,類中有_age和_name兩個實例變量,堆Student類對象進行歸檔和反歸檔操作
Student類
Student.h
//對於一個自定義的類想要進行歸檔和反歸檔操作必須遵守NSCoding協議
//遵守NSCoding協議
#import
//.h文件類的聲明後面加上<協議名>,表示該類遵守這個協議
@interface Student : NSObject
@property (assign, nonatomic)int age;
@property (copy, nonatomic)NSString *name;
//協議中的內容
- (void)encodeWithCoder:(NSCoder *)aCoder;//歸檔操作的時候自動被調用
- (id)initWithCoder:(NSCoder *)aDecoder;//反歸檔的時候自動被調用
@en
Student.m
//.m實現協議中的方法
#import "Student.h"
@implementation Student
//歸檔的時候調用
- (void)encodeWithCoder:(NSCoder *)aCoder{
//- (void)encodeInt:(int)intv forKey:(NSString *)key;
//作用:歸檔int類型的數據
//key:歸檔的格式,歸檔格式任意但是以什麼格式歸檔就需要以什麼格式反歸檔
[aCoder encodeInt:self.age forKey:@"age"];
//- (void)encodeObject:(id)objv forKey:(NSString *)key;
//作用:歸檔oc對象
[aCoder encodeObject:self.name forKey:@"name"];
}
- (id)initWithCoder:(NSCoder *)aDecoder{
//- (int)decodeIntForKey:(NSString *)key;
//作用:反歸檔int類型數據
if(self = [super init]){
self.age = [aDecoder decodeIntForKey:@"age"];
self.name = [aDecoder decodeObjectForKey:@"name"];
}
return self;
}
viewController.m
NSString *pathDesktop = @"/Users/mac/Desktop";
Student *std = [[Student alloc] init];
std.age = 10;
std.name = @"xiao xin";
[NSKeyedArchiver archiveRootObject:std toFile:[pathDesktop stringByAppendingString:@"/歸檔文件student"]];
Student *stdFromArchiver = [NSKeyedUnarchiver unarchiveObjectWithFile:[pathDesktop stringByAppendingString:@"/歸檔文件student"]];
NSLog(@"age is %d name is %@", stdFromArchiver.age, stdFromArchiver.name);
}
**
Json
**
(1) 什麼是JSON
JSON是一種輕量級的數據交換格式, JSON語法是 JavaScript 語法的子集;
JSON 數據的書寫格式是: 名稱:值 構成鍵值對。(類似於OC字典的鍵值對)
(2) JSON的基本語法
名稱/值對 包括字段名稱(在雙引號中), 後面寫一個冒號,然後是值。如 “firstName”:”tom”
JSON的值可以是:
a. 數字 (整數或浮點數)
b. 字符串 (在雙引號中)
c. 邏輯值 (true 或 false)
d. 數組 (在方括號中)
e. 對象 (在花括號中)
f. null
(3) JSON結構
JSON有數組和字典兩種結構 ; 通過這兩種結構可以表示各種復雜的結構;
1:數組:數組在json中是中括號‘[]’括起來的內容,數據結構為[“java”,”javascript”,”vb”,…],類似於OC中的數組
2:對象:對象在json中表示為“{}”括起來的內容,數據結構為 {key:value,key:value,…}的鍵值對的結構,類似於oc中的字典結構
json的結構也決定了json最終只能轉換成數組或字典類型的對象
@{key : value}
(4)json文件解析(analysis)
本地json解析步驟:
1:首先調用NSString的
+ (id)stringWithContentsOfFile:(NSString )path encoding:(NSStringEncoding)enc error:(NSError *)error;
方法將文件讀成字符串
2:然後調用NSString的
- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding;
把字符串轉換成NSData二進制數據
3:調用系統類NSJSONSerialization的
+ (id)JSONObjectWithData:(NSData )data options:(NSJSONReadingOptions)opt error:(NSError *)error;
方法進行解析,最後解析為NSArray或者NSDictionary
例子:對本地jsonUserList.txt文件進行解析
//json文件的解析
void JsonAnalysis1(void){
NSString *pathDesktop = @"/Users/mac/Desktop";
//1:讀取json文件內容保存在string
NSString *string = [NSString stringWithContentsOfFile:[pathDesktop stringByAppendingString:@"/json/jsonUserList.txt"] encoding:NSUTF8StringEncoding error:nil];
//2:把string轉換成data
NSData *dataFromString = [string dataUsingEncoding:NSUTF8StringEncoding];
//3:將data進行json解析
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:dataFromString options:NSJSONReadingMutableContainers error:nil];
NSLog(@"%@", dictionary);
}
NSUserDefaults
(1)NSUserDefaults是一個單例,在整個程序中只有一個實例對象,他可以用於數據的永久保存,而且簡單實用,適合存儲輕量級的本地數據,比如要保存一個登陸界面的數據,用戶名、密碼之類的,使用NSUserDefaults就比較簡單了。
(2)NSUserDefaults支持的數據格式有:NSNumber(Integer、Float、Double),NSString,NSDate,NSArray,NSDictionary,BOOL類型。
(3)例子
//將NSString 對象存儲到 NSUserDefaults 中
NSString *string = @"小明";
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
[user string forKey:@"name"];
將數據取出,代碼如下:
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
NSString *string = [ user objectForKey:@"name"];
注意:對相同的Key賦值約等於一次覆蓋,要保證每一個Key的唯一性
注意:
NSUserDefaults 存儲的對象全是不可變的(這一點非常關鍵,弄錯的話程序會出bug),例如,如果我想要存儲一個 NSMutableArray 對象,我必須先創建一個不可變數組(NSArray)再將它存入NSUserDefaults中去,代碼如下:
NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"123",@"234", nil];
NSArray * array = [NSArray arrayWithArray:mutableArray];
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
[user setObject:array forKey:@"記住存放的一定是不可變的"];
取出數據是一樣的,想要用NSUserDefaults中的數據給可變數組賦值
先給出一個錯誤的寫法:
/*-------------------------錯誤的賦值方法-------------------*/
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
//這樣寫後,mutableArray 就變成了不可變數組了,如果你要在數組中添加或刪除數據就會出現bug
NSMutableArray *mutableArray = [user objectForKey:@"記住存放的一定是不可變的"];
正確的寫法:
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
//可以用alloc 方法代替
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:[user objectForKey:@"記住存放的一定是不可變的"]];
(4)使用 NSUserDefaults 存儲自定義對象
如果存儲的數據量比較大,一般選擇用SQLite來存儲。SQLite的介紹放在下一篇章節。
內存洩露,是Android開發者最頭疼的事。可能一處小小的內存洩露,都可能是毀千裡之堤的蟻穴。 怎麼才能檢測內存洩露呢? AndroidStudio 中Memory控件台
LBS(Location Based Services)直譯的話就是基於地理位置的服務,這裡面至少有兩層意思,第一要能輕易的獲取當前的地理位置,譬如經緯度海拔等,另一個就
支付寶有上線一項繳費服務新功能——ETC繳費功能,用戶可以通過支付寶對武漢地區的ETC進行繳費,這個功能暫時面對武漢市的廣大司機朋友
孩放假,在家沒事,所以把手機丟給他玩,沒想到他自己琢磨,竟然設置了密碼。各種試,各種問,都沒解開。實在不想清空數據,因為裡面記了很多賬,還有不少重要的短消息