IOS高级编程之二:IOS的数据存储与IO
一、應用程序沙盒
???? IOS應用程序職能在系統為該應用所分配的文件區域下讀寫文件,這個文件區域就是應用程序沙盒。所有的非代碼文件如:圖片、聲音、映象等等都存放在此。
在mac中command+shift+G命令,然后輸入users/用戶名/library命令進入庫,然后依次進入application support/iphone simulator/版本/applications文件夾,這里面的各個文件夾對應著各個應用程序。
Documents:除了基于NSUserDefaults的首選項設置外,應用程序的數據、文件都保存在該目錄下
Library:基于NSUserDefaults的首選項參數保存在Library/Preferences下
tmp:應用程序存儲臨時文件,ios同步時itunes不會同步這里面的數據,當應用程序不在需要這些文件時,應當刪除以避免占用空間。
獲取documents路徑:
1 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES); 2 NSString *dd = [paths objectAtIndex:0];獲取tmp目錄:
1 NSString *tempPath = NSTemporaryDirectory();那么我們在保存數據時使用哪種發式比較好呢,這個當然還要具體情況具體對待。
當保存小數據量的數據時,可以使用NSArray或者NSDictionary,調用writeToFile:atomically:方法寫入一個文件,使用時讀取文件內容即可。
當保存大數據量的數據時,可以選擇使用sqllite,ios提供了CoreData框架。
?
二、應用程序參數與用戶默認設置
1、使用Settings Bundle
Settings Bundle時應用程序中的一組特殊文件,用于保存較簡單的各種配置信息。如果使用了Settings Bundle,ios自帶的設置應用則會顯示你的app
2、使用NSUserDefaults讀取、保存應用程序參數
NSUserDefaults是一個單例類,每個應用程序只有一個NSUserDefaults對象,Settings Bundle設置的參數,也可以通過NSUserDefaults來讀取和設置
獲取NSUserDefaults的方法:
1 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];獲取NSUserDefaults對象后,可以獲取和設置應用程序參數
xxForKey:(NSString *) key? =>xx表示各種類型,根據key獲取值
setBool:(xxx) value forKey:(NSString *) key =>設置參數
設置完參數后,調用synchronize方法進行保存。
3、屬性列表
屬性列表就是文章開始提到的利用NSArray和NSDictionary將數據寫入到文件的保存方法。
但是有一些限制,只有下列類型的值保存到NSArray和NSDictionary中才可以直接調用writeToFile方法執行保存:
NSArray、NSMutableArray、NSDictionary、NSMutableDictionary、NSData、NSMutableData、NSString、NSMutableString、NSValue、NSNumber
如果NSArray和NSDictionary保存了我們自定義的類,那么將不能直接調用writeToFile方法執行保存。(可以考慮使用對象歸檔的方法進行保存)
1 //使用屬性列表保存3個用戶的賬號密碼 2 accountList = [[NSMutableArray alloc] init]; 3 [accountList addObject:[NSDictionary 4 dictionaryWithObjects:[NSArray arrayWithObjects:@"loginname",@"loginpwd", nil] 5 forKeys:[NSArray arrayWithObjects:@"305213781",@"123123", nil]]]; 6 [accountList addObject:[NSDictionary 7 dictionaryWithObjects:[NSArray arrayWithObjects:@"loginname",@"loginpwd", nil] 8 forKeys:[NSArray arrayWithObjects:@"475782389",@"123456", nil]]]; 9 [accountList addObject:[NSDictionary 10 dictionaryWithObjects:[NSArray arrayWithObjects:@"loginname",@"loginpwd", nil] 11 forKeys:[NSArray arrayWithObjects:@"330577588",@"123456789", nil]]]; 12 [accountList writeToFile:[self filePath] atomically:YES]; 13 14 //使用UIActionSheet提示用戶保存成功 15 UIActionSheet *sheet =[[UIActionSheet alloc] initWithTitle:@"保存成功" delegate:nil cancelButtonTitle:nil destructiveButtonTitle:@"確定" otherButtonTitles:nil, nil]; 16 [sheet showInView:self.view];?
4、使用Sqlite3數據庫
1)為項目增加libsqlite3.dylib,這是一個原生的C函數庫
常用函數:
int sqlite3_close(sqlite3 *):關閉sqlite3 *所代表的數據連接,并釋放底層數據庫連接資源。在調用該函數之前,必須先調用sqlite3_finalize()函數,調用sqlite3_blob_close()函數關閉所有的blob處理器,否則將會返回SQLITE_BUSY
int sqlite3_exec(sqlite3*,const char *sql, int (*callback)(void*, int ,char**,char**),void *,char **errmsg):用于執行沒有返回值的sql語句
sqlite3_int64? sqlite3_last_insert_rowid(sqlite3*):返回sqlite3代表的數據庫最后一次插入行的id
int sqlite3_changes(sqlite3*):執行某條dml語句后,返回受影響行數
void sqlite3_interrupt(sqlite3*):中斷一個長時間執行的查詢語句
int sqlite3_complete(const char *sql):用于判斷sql語句是否執行完成
int sqlite3_open(const char * filename,sqlite3 ** ppdb):打開與filename文件的鏈接,并讓ppdb參數引用被打開的數據庫連接
const char *sqlite3_sql(sqlite3_stmt *pStmt):用于提取sqlite3_stmt(預編譯SQL語句產生的結果)中包裝的sql語句
等等。。。太多了不一一列舉了
操作sqlite數據庫的大致步驟如下:
1、調用sqlite3_open方法打開與數據庫的連接
2、執行語句
3、sqlite3_close函數關閉數據庫連接
?
2)使用Core Data框架
Core Data框架是一個純粹的面向對象的框架,允許開發者以面向對象的方式持久化操作SQLite數據庫。core data底層的持久化存儲方式可以是Sqlite數據庫,也可以是xml,也可以是內存。
Core Data的核心概念是實體,由Core Data管理的模型對象,它必須是NSManagedObject類或者它的子類的實例。
Core Data應用中的核心API有如下幾個:
托管對象模型(NSManagedObjectModel):該對象負責管理整個應用的所有實體以及實體之間的關聯關系。當開發者使用Xcode的圖形界面設計了實體與實體間的關聯關系之后,需要使用該對象來加載、管理應用的托管對象模型
持久化存儲協調器(NSPersistentStoreCoordinator):負責管理底層的存儲文件,例如sqlite數據庫等等
托管對象上下文(NSManagedObjectContext):該對象是Core Data的核心,增刪改查都需要通過它來進行
實體描述(NSEntityDescription):關于某個實體的描述信息
抓取請求(NSFetchRequest):該對象封裝了查詢實體的請求,包括程序需要查詢哪些實體、查詢條件、排序規則等
使用Core Data持久化的步驟大致如下
1、創建NSManagedObjectModel對象來加載管理應用對應的托管對象模型
2、以NSManagedObjectModel對象為基礎,根據實際需要創建NSPersistentStoreCoordinator對象,該對象確定底層數據的存儲形式
3、以NSManagedObjectModel對象為基礎,創建NSManagedObjectContext對象
4、對于普通的增、刪、改操作,需要分別先新建實體、刪除實體、修改實體,然后調用NSManagedObjectContext對象的save方法,保存修改
5、如果執行查詢,需要先創建NSFetchRequest對象,在調用NSManagedObjectContext對象的executeFetchRequest:error:方法,返回所有匹配條件的實體組成的NSArray
?
使用Core Data的例子來和大家一起學習。
首先,創建一個創建一個Single View Application,下面有個Use Core Data選項,打上勾,之后Xcode已經為你做好了準備工作,打開AppDelete.m就可以看到
三個重要的對象NSManagedObjectModel、NSPersistentStoreCoordinator、NSManagedObjectContext的實例已經為你設置好了,當我們要執行相關增刪改查時,直接調用委托類的managedObjectContext屬性操作即可。
在創建項目后,會發現項目中有一個**.xcdatamodeld文件,點擊后就會出現實體模型設計界面
在剛剛的設計視圖中添加一個類:EventEntity,添加兩個屬性=》happenDate(Data)、name(string) 單擊Xcode主菜單的Editor=》Create NSManagedObject Subclass菜單,來創建一個子類,之后你的項目中就會創建一個類:EventEntity : NSManagedObject 先完成一些準備工作,獲取appdelete對象,定義一個nameCount變量記錄添加了幾個對象 1 #import "SqliteViewController.h" 2 #import "EventEntity.h" 3 #import <Foundation/Foundation.h> 4 #import <CoreData/CoreData.h> 5 #import "AppDelegate.h" 6 7 @interface SqliteViewController () 8 @property (nonatomic,weak) AppDelegate *appDelete; 9 @property (nonatomic) int nameCount; 10 @end 11 12 @implementation SqliteViewController 13 14 - (void)viewDidLoad { 15 [super viewDidLoad]; 16 self.nameCount = 1; 17 // Do any additional setup after loading the view. 18 self.appDelete = (AppDelegate *)[UIApplication sharedApplication].delegate; 19 } 20 21 - (void)didReceiveMemoryWarning { 22 [super didReceiveMemoryWarning]; 23 // Dispose of any resources that can be recreated. 24 }?
5.1 添加實體 第一步:調用NSEntityDescription的 insertNewObjectForEntityForName:(NSString *) inManagedObjectContext:(NSManagedObjectContext *)方法,第一個參數為實體名,第二個參數為上下文對象 第二部:為新實體設置屬性 第三部:調用NSManagedObjectContext對象的save方法保存。 1 //添加操作 2 - (IBAction)btnAdd_Tap:(id)sender { 3 //創建一個新實體 4 EventEntity *ee = [NSEntityDescription insertNewObjectForEntityForName:@"EventEntity" inManagedObjectContext:self.appDelete.managedObjectContext]; 5 //給實體設置屬性 6 ee.happenDate = [NSDate date]; 7 ee.name = [NSString stringWithFormat:@"名字%d",self.nameCount++]; 8 9 //定義NSError對象接收錯誤信息 10 NSError *error; 11 if ([self.appDelete.managedObjectContext save:&error]) { 12 [[[UIAlertView alloc] initWithTitle:@"添加操作" message:[NSString stringWithFormat:@"添加成功,添加的實體的name是:%@",ee.name] delegate:nil cancelButtonTitle:@"好的" otherButtonTitles:nil, nil] show]; 13 }else 14 { 15 NSLog(@"保存時出現錯誤:%@,%@",error,[error userInfo]); 16 } 17 }?
5.2 刪除實體 1 //刪除操作 2 - (IBAction)btnRemove_Tap:(id)sender { 3 //獲取要刪除的實體 4 EventEntity *entity = [self getEntityByName:@"名字1"]; 5 //從上下文對象中刪除該實體 6 [self.appDelete.managedObjectContext deleteObject:entity]; 7 NSError *error; 8 if (![self.appDelete.managedObjectContext save:&error]) { 9 NSLog(@"刪除時出現錯誤:%@,%@",error,[error userInfo]); 10 } 11 }5.3 修改實體
1 //更新操作 2 - (IBAction)btnUpdate_Tap:(id)sender { 3 //獲取要刪除的實體 4 EventEntity *entity = [self getEntityByName:@"名字1"]; 5 //修改實體屬性 6 entity.happenDate = [NSDate date]; 7 NSError *error; 8 if (![self.appDelete.managedObjectContext save:&error]) { 9 NSLog(@"刪除時出現錯誤:%@,%@",error,[error userInfo]); 10 } 11 }5.4 查詢
1 //根據名字查詢一個對象 2 -(EventEntity *)getEntityByName:(NSString *) name 3 { 4 //創建抓取數據的請求對象 5 NSFetchRequest *request = [[NSFetchRequest alloc] init]; 6 7 //設置要抓取哪種類型的實體 8 NSEntityDescription *des = [NSEntityDescription entityForName:@"EventEntity" inManagedObjectContext:self.appDelete.managedObjectContext]; 9 10 //設置抓取實體 11 [request setEntity:des]; 12 //定義抓取條件 13 NSPredicate * qcmd = [NSPredicate predicateWithFormat:@"name = %@ ",name]; 14 [request setPredicate:qcmd]; 15 16 NSError *error = nil; 17 //執行查詢請求 18 NSArray *result = [[self.appDelete.managedObjectContext executeFetchRequest:request error:&error] copy]; 19 if (error!=nil) { 20 NSLog(@"查詢單個時出現錯誤:%@,%@",error,[error userInfo]); 21 return nil; 22 } 23 if (result.count==0) { 24 return nil; 25 } 26 return result[0]; 27 } 28 29 //獲得所有實體 30 -(NSArray *)getAllEntities 31 { 32 //創建抓取數據的請求對象 33 NSFetchRequest *request = [[NSFetchRequest alloc] init]; 34 35 //設置要抓取哪種類型的實體 36 NSEntityDescription *des = [NSEntityDescription entityForName:@"EventEntity" inManagedObjectContext:self.appDelete.managedObjectContext]; 37 38 //設置抓取實體 39 [request setEntity:des]; 40 41 NSError *error = nil; 42 //執行查詢請求 43 NSArray *result = [[self.appDelete.managedObjectContext executeFetchRequest:request error:&error] copy]; 44 //如果沒有數據返回nil 45 if (error!=nil && result == 0) { 46 return nil; 47 } 48 return result; 49 50 }?
轉載于:https://www.cnblogs.com/chengzi/p/4478763.html
總結
以上是生活随笔為你收集整理的IOS高级编程之二:IOS的数据存储与IO的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深信服云桌面linux客户端,深信服桌面
- 下一篇: 读《About Face 4 交互设计精