1.歸檔是指用某種格式來保存一個或多個對象,以便之後還原這些對象的過程。歸檔是將數據持久化的一種方式(所謂數據持久化,就是指在IOS開發過程當中,將數據保存到本地,可以讓程序的運行更加流暢)。sql
2.想要歸檔的數據對象,須要遵照NSCoding協議,而且該對象對應的類必須提供encodeWithCoder:和initWithCoder:方法。數據庫
3.歸檔就是將臨時數據保存成本地文件。數組
4.歸檔的缺點:歸檔的形式來保存數據,只能一次性歸檔保存以及一次性解壓。因此只能針對小量數據,並且對數據操做比較笨拙,即若是想改動數據的某一小部分,仍是須要解壓整個數據或者歸檔整個數據。xcode
1.侷限:數據類型只支持 NSString、NSDictionary、NSArayy、NSData、NSNumber(若是你想的話,能夠將基本數據類型轉換爲NSNumber再進行歸檔)。瀏覽器
2.比較方便,設置好歸檔路徑,一句話歸檔,一句話解檔。app
3.歸檔文件格式:通常保存.plist文件。學習
/**** NSString和NSMutableString XML歸解檔 ****/ NSString *str = @"hello world"; NSString *path = [[NSHomeDirectory() stringByAppendingPathComponent:@"Desktop"]stringByAppendingPathComponent:@"hello.txt"]; // atomically:這個參數意思是若是爲YES,則保證文件的寫入原子性。就是說會先建立一個臨時文件,直到文件內容寫入成功再導入到目標文件裏.若是爲NO,則直接寫入目標文件裏.
[str writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil]; // 這裏會覆蓋原來的內容
[@"hello world 2" writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil]; NSString *str2 = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
/**** NSData和NSMutableData XML歸解檔 ****/
// 任何對象均可以轉化爲NSData
NSData *data = [@"hello world" dataUsingEncoding:NSUTF8StringEncoding]; NSString *path2 = [[NSHomeDirectory() stringByAppendingPathComponent:@"Desktop"]stringByAppendingPathComponent:@"data.txt"]; //歸檔
[data writeToFile:path2 atomically:YES]; //解檔
[NSData dataWithContentsOfFile:path2];
/**** NSArray及NSMutableArray XML歸解檔 ****/
NSArray *array = @[@"test",@"test2"];
NSString *path3 = [[NSHomeDirectory() stringByAppendingPathComponent:@"Desktop"]stringByAppendingPathComponent:@"array.plist"]; // 歸檔
[array writeToFile:path3 atomically:YES]; // 解檔
NSArray *array = [NSArray arrayWithContentsOfFile:path3];
/**** NSArray XML歸解檔 ****/ NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"one",@"1",@"two",@"2", nil]; NSString *path4 = [[NSHomeDirectory() stringByAppendingPathComponent:@"Desktop"]stringByAppendingPathComponent:@"dic.plist"]; // 歸檔
[dic writeToFile:path4 atomically:YES]; // 解檔
NSDictionary *ddic = [NSDictionary dictionaryWithContentsOfFile:path3];
1.將各類類型的對象存儲到文件中,並且不只僅是字符串、數組和字典類型,有一種更靈括的方法。就是利用NSKeyedArchiver類建立帶鍵(keyed)的檔案來完成。實現對咱們自定義的類進行歸檔。atom
2.序列化與反序列化:將一個Objective-C對象轉換成NSData的操做叫作對象的序列化;而將一個NSData轉換成Objective-C對象的操做叫作對象的反序列化。一個Objective-C對象須要經過實現NSCoding協議以便支持序列化與反序列化spa
3.模擬場景:有一個學生類,學生擁有三個屬性name、age、book(一本書),其中book對應Book類,Book類中擁有一個屬性bookName,歸檔一個數組,數組中有兩個student對象。3d
Student類
#import <Foundation/Foundation.h>
#import "Book.h"
@interface Student : NSObject<NSCoding> @property (nonatomic,copy)NSString *name; @property (nonatomic,assign)int age; // 除Student類以外,這裏有一個自定義類型Book,因此Book類也須要實現NSCoding協議,從而進行歸檔
@property (nonatomic,strong)Book *book; @end
#import "Student.h"
@implementation Student -(void)encodeWithCoder:(NSCoder *)aCoder { // 歸檔姓名(NSString 對象)
[aCoder encodeObject:self.name forKey:@"name"]; // 歸檔年齡(基本數據類型,若是是其它基本數據類型調用相應的encode方法)
[aCoder encodeInt:self.age forKey:@"age"]; // 歸檔自定義類(Book)
[aCoder encodeObject:self.book forKey:@"book"]; } -(instancetype)initWithCoder:(NSCoder *)aDecoder { if(self = [super init]) { //歸檔的key 寫的什麼 對應屬性解檔key就寫什麼
self.name = [aDecoder decodeObjectForKey:@"name"]; self.age = [aDecoder decodeInt32ForKey:@"age"]; self.book = [aDecoder decodeObjectForKey:@"book"]; } return self; } @end
一樣的,Book類也要實現<NSCoding>協議並重寫相應的兩個方法。
NSKeyedArchiver歸檔實現代碼:
// 這裏student、book對象初始化的代碼就不列了
NSArray *stuArr = @[stu1,stu2]; if ([NSKeyedArchiver archiveRootObject:stuArr toFile:path5]) { NSLog(@"寫入成功"); } NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithFile:path5];
如此,即可以實現自定義對象的歸檔和解檔了。
1.NSUserDefaults是一個單例類,如它的名字同樣,用於永久保存一些用戶對於應用程序的配置之類的簡單數據,其簡單而又實用
2.NSUserDefaults支持的數據類型同XML歸檔同樣,僅僅用於保存一些程序配置信息的話徹底是能夠勝任的。
// 保存
NSString *passWord = @"88888888"; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:passWord forKey:@"passWord"]; // 經過存儲時候key取出相應的value
NSString *passWord = [ user objectForKey:@"passWord"];
3.固然,NSUserDefaults也能夠存儲自定義類,同NSKeyedArchiver歸檔類似,爲自定義類實現<NSCoding>協議,而後
// 將student類型變爲NSData類型 (這裏採用NSKeyedArchiver中的例子Student爲例) NSData *data = [NSKeyedArchiver archivedDataWithRootObject:student];
// NSUserDefaults是支持NSData類型
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
[user setObject:data forKey:@"student"];
1.使用sqlite以前須要瞭解一下基本的一些sql語句,很簡單,學會建表、增刪改查的語句就好了。(學習的話這裏推薦火狐瀏覽器下的sqlite組件)
2.使用:在工程中導入包「libsqlite3.dylib」,在類中導入頭文件#import <sqlite3.h>
Xcode7注意了,當你去導入sqlite3.dylib的時候(其實那兩個.tbd文件就是之前老版本的替代了),你會發現根本找不到這個包,由於這個包自xcode7以後就被蘋果隱藏掉了
若是你想要使用老版本的,請繼續下面的操做。
當點擊「+」彈出窗口以後,選擇「add other」,快捷鍵 CMD+Shift+G (Go to the folder),輸入/usr/lib後,進入隱藏的界面,在文件目錄下找到,而後添加你須要的 *.dylib,如libsqlite3.dylib文件。
3.sqlite使用,這裏講一下我以前作的一個增刪改查的demo,下面貼上代碼
User類:
#import <Foundation/Foundation.h>
@interface User : NSObject @property (nonatomic,retain)NSData *icon; // 頭像
@property (nonatomic,copy)NSString *name; // 名字
@property (nonatomic,copy)NSString *phone; // 電話號碼
@property (nonatomic,assign)int age; // 年齡
@property (nonatomic,assign)NSInteger ID; @end
UserDBManager類
// // UserDBManager.h // Sqlite3基礎操做 // // Created by silence on 15-8-15. // Copyright (c) 2015年 hawode06. All rights reserved. // #import <Foundation/Foundation.h> #import <sqlite3.h> #import "User.h" #define insert @"INSERT" @interface UserDBManager : NSObject // 插入數據 -(BOOL)insertUser:(User *)user; // 刪除數據 -(BOOL)delePerson:(NSInteger)idd; // 修改數據 -(BOOL)updatePerson:(User *)User; // 查詢全部 -(NSArray *)queryUser; // 經過姓名查詢用戶 -(NSArray *)searchWithName:(NSString *)str; @end // // UserDBManager.m // Sqlite3基礎操做 // // Created by silence on 15-8-15. // Copyright (c) 2015年 hawode06. All rights reserved. // #import "UserDBManager.h" @interface UserDBManager () @property (nonatomic,copy)NSString *dbPath; @property (nonatomic,assign)sqlite3 *dataBase; @end @implementation UserDBManager -(BOOL)openDB { NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; NSString *dbPath = [path stringByAppendingPathComponent:@"user.db"]; NSLog(@"%@",dbPath); NSFileManager *fm = [NSFileManager defaultManager]; if([fm fileExistsAtPath:dbPath]) { //若是存在就打開 bool result = sqlite3_open([dbPath UTF8String], &_dataBase) == SQLITE_OK; if (result) { return YES; } else { sqlite3_close(_dataBase); return NO; } } else { //打開數據庫 返回值sqlite_ok 表明打開成功 if (sqlite3_open([dbPath UTF8String], &_dataBase) == SQLITE_OK) { NSString *sql = @"create table if not exists \"User\"(\"id\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,\"name\" varchar,\"phone\" varchar,\"age\" INTEGER NOT NULL DEFAULT 1,\"image\" blob)"; //執行建立表的sql語句 sqlite3_stmt *stateMent; //解析sql語句 第一個 數據庫變量 第二個sql語句 sql語句的長度 -1表明自動計算 stetement變量 int pResult = sqlite3_prepare_v2(_dataBase, [sql UTF8String], -1, &stateMent, nil); //解析sql 語句失敗 if (pResult != SQLITE_OK) { NSLog(@"建立表失敗"); } else { //執行sql 語句 成功 if (sqlite3_step(stateMent) == SQLITE_DONE) { NSLog(@"建立表成功"); } else { NSLog(@"建立表失敗"); } } //釋放statement sqlite3_finalize(stateMent); return YES; } else { sqlite3_close(_dataBase); return NO; } } return YES; } -(BOOL)insertUser:(User *)user { if ([self openDB]) { NSString *addSql = @"insert into User (name,phone,age,image) values (?,?,?,?)"; sqlite3_stmt *stateMent; //解析sql語句 第一個 數據庫變量 第二個sql語句 sql語句的長度 -1表明自動計算 stetement變量 int result = sqlite3_prepare_v2(_dataBase, [addSql UTF8String], -1, &stateMent, nil); //給sql語句裏的’?‘ 賦值 第一個參數是statement 第二個是‘?’的位置 以1開頭 //姓名 sqlite3_bind_text(stateMent, 1, [user.name UTF8String], -1, SQLITE_TRANSIENT); //電話 sqlite3_bind_text(stateMent, 2, [user.phone UTF8String], -1, SQLITE_TRANSIENT); //年齡 sqlite3_bind_int(stateMent, 3, user.age); //頭像 sqlite3_bind_blob(stateMent, 4, [user.icon bytes], (int)user.icon.length, nil); if (result == SQLITE_OK) { //執行sql 語句 成功 if (sqlite3_step(stateMent) == SQLITE_DONE) { NSLog(@"插入成功"); } else { NSLog(@"插入失敗"); } } //釋放statement sqlite3_finalize(stateMent); //關閉數據庫 sqlite3_close(_dataBase); return YES; } return NO; } -(BOOL)delePerson:(NSInteger)idd { if ([self openDB]) { NSString *deleSql = [NSString stringWithFormat:@"delete from User where id = %ld",idd]; // 經過id刪除user表中的用戶數據 sqlite3_stmt *stateMent; int result = sqlite3_prepare_v2(_dataBase, [deleSql UTF8String], -1, &stateMent, nil); if (result == SQLITE_OK) { //執行sql 語句 成功 if (sqlite3_step(stateMent) == SQLITE_DONE) { NSLog(@"刪除成功"); } else { NSLog(@"刪除失敗"); } } //釋放statement sqlite3_finalize(stateMent); //關閉數據庫 sqlite3_close(_dataBase); return YES; } return NO; } -(NSArray *)queryUser { NSMutableArray *arr; if ([self openDB]) { arr = [NSMutableArray arrayWithCapacity:0]; NSString *sql = @"select * from User"; //sql 語句:查詢User表中的全部數據 sqlite3_stmt *statement; //解析sql語句 第一個 數據庫變量 第二個sql語句 sql語句的長度 -1表明自動計算 stetement變量 int pResult = sqlite3_prepare_v2(_dataBase, [sql UTF8String], -1, &statement, nil); //解析sql語句成功 if (pResult == SQLITE_OK) { while (sqlite3_step(statement) == SQLITE_ROW) { User *user = [[User alloc] init]; int num = sqlite3_column_int(statement, 0); char *cName = (char *)sqlite3_column_text(statement, 1); char *cPhone = (char *)sqlite3_column_text(statement, 2); int age = sqlite3_column_int(statement, 3); char *iconBytes = (char *)sqlite3_column_blob(statement, 4); NSInteger iconDataLen = sqlite3_column_bytes(statement, 4); user.name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding]; user.phone = [NSString stringWithCString:cPhone encoding:NSUTF8StringEncoding]; user.age = age; user.icon = [NSData dataWithBytes:iconBytes length:iconDataLen]; user.ID = num; [arr addObject:user]; } //釋放statement sqlite3_finalize(statement); } //關閉數據庫 sqlite3_close(_dataBase); } return arr; } -(NSArray *)searchWithName:(NSString *)str { NSMutableArray *arr; if ([self openDB]) { arr = [NSMutableArray arrayWithCapacity:0]; NSString *sql = [NSString stringWithFormat:@"select * from User where name like '%%%@%%'",str]; NSLog(@"sql語句:%@",sql); sqlite3_stmt *statement; //解析sql語句 第一個 數據庫變量 第二個sql語句 sql語句的長度 -1表明自動計算 stetement變量 int pResult = sqlite3_prepare_v2(_dataBase, [sql UTF8String], -1, &statement, nil); //解析sql語句成功 if (pResult == SQLITE_OK) { while (sqlite3_step(statement) == SQLITE_ROW) { User *user = [[User alloc] init]; int num = sqlite3_column_int(statement, 0); char *cName = (char *)sqlite3_column_text(statement, 1); char *cPhone = (char *)sqlite3_column_text(statement, 2); int age = sqlite3_column_int(statement, 3); char *iconBytes = (char *)sqlite3_column_blob(statement, 4); NSInteger iconDataLen = sqlite3_column_bytes(statement, 4); user.name = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding]; user.phone = [NSString stringWithCString:cPhone encoding:NSUTF8StringEncoding]; user.age = age; user.icon = [NSData dataWithBytes:iconBytes length:iconDataLen]; user.ID = num; [arr addObject:user]; } NSLog(@"數組%@",arr); //釋放statement sqlite3_finalize(statement); } //關閉數據庫 sqlite3_close(_dataBase); } return arr; } @end
// 修改用戶數據的好像當時懶得作,並無實現那個方法,看懂了另外幾個增、查、刪的實現也就差很少了,基本操做數據庫的流程都同樣,只是執行不一樣的sql語句而已。
4.界面的代碼就不貼了,大體是這樣的
經過前往文件夾,能夠看到目錄下面有一個後綴名爲db的文件
打開以後,也能夠看到其中的三條數據(這裏我使用的是mac山觀點SQLite.app軟件)
原本準備把FMDB的使用介紹一塊兒寫在這裏的,但想了一下,仍是待之後再寫在三方庫學習歸類裏面吧,多複習老是對本身有好處的。(FMDB是通過別人封裝好的數據庫操做三方庫,使用起來很是簡單)
還沒去了解如何使用,改天再本身學一下再寫吧。