iOS常用的存儲方式介紹
在iOS App開發過程中經常需要操作一些需要持續性保留的數據,比如用戶對於App的相關設置、需要在本地緩存的數據等等。本文針對OC中經常使用的一下存儲方式做了個整理。
常用的存儲工具/方式:
NSUserDefaults類
Plist文件
解歸檔
手動存放沙盒
// sqlite
CoreData
第三方數據存儲框架
1. NSUserDefaults
一般對於一些基本的用戶設置,因為數據量很小,我們可以使用OC語言中的 NSUserDefaults類來進行處理。使用方法很簡單,只需要調用類中的方法即可:
NSMutableArray *mutArr = [[NSMutableArray alloc]initWithObjects:@"1", nil];
//存入數組並同步
[[NSUserDefaults standardUserDefaults] setObject:mutArr forKey:@"mutableArr"];
[[NSUserDefaults standardUserDefaults] synchronize];
//讀取存入的數組 打印
NSArray *arr = [[NSUserDefaults standardUserDefaults] objectForKey:@"mutableArr"];
NSLog(@"%@",arr);
NSUserDefaults類除了可以存儲數組、字典、NSdata外,還可以直接存儲OC基本類型屬性。但是不能直接作用到自定義對象,如果是自定義對象需要進行歸檔操作,這里后面會講到。
2. Plist文件
Plist文件作為Xcode的一種資源包,也可以作為一種存儲工具。
1.在項目中創建Plist文件。 在項目中創建的好處是文件的可視化,我們可以很直觀的看到文件的內容,同時Xcode還提供了直接操作文件的功能。便於我們對文件內容的增刪改查。這種方式的缺點是項目中的plist文件一般作為固態的數據形勢保存,對於經常需要改動的數據就不好操作了。
獲取文件中的數據代碼
NSString *string = [[NSBundle mainBundle] pathForResource:@"testPlist" ofType:@"plist"];
NSDictionary *dic = [NSDictionary dictionaryWithContentsOfFile:string];
NSLog(@"%@",dic); //打印文件中的內容
2.代碼讀寫Plist文件。避免了在項目中創建Plist文件導致不便更改的麻煩。
//創建一個plist文件 testPlist
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *plistpath = [paths objectAtIndex:0]; NSLog(@"path = %@",plistpath); NSString *filename=[plistpath stringByAppendingPathComponent:@"testPlist.plist"]; NSFileManager* fm = [NSFileManager defaultManager]; [fm createFileAtPath:filename contents:nil attributes:nil]; //寫入內容 NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:@"test",nil]; [dic writeToFile:filename atomically:YES]; //讀文件 NSDictionary* dic2 = [NSDictionary dictionaryWithContentsOfFile:filename]; NSLog(@"dic is:%@",dic2);
3.解歸檔
之前說了,不管是NSUserDefaults 或者是 plist 都不能對自定義的對象進行存儲,OC提供了解歸檔恰好解決這個問題。 解歸檔針對的是一個對象,假設我們現在有一個TestModel的類,需要進行歸檔和接檔,上代碼。
對象的.h文件
#import <Foundation/Foundation.h>
@interface TestModel : NSObject <NSCoding> //解歸檔需要遵循Nscoding協議,並實現相關方法
@property (nonatomic,strong) NSString *name; @property (nonatomic,assign) NSInteger age; @property (nonatomic,strong) NSString *sex; @end
對象的.m文件
#import "TestModel.h"
#define Name @"name"
#define Age @"age"
#define Sex @"sex"
@implementation TestModel
//需要實現NSCoding中的協議的兩個方法
- (id)initWithCoder:(NSCoder *)aDecoder{ if (self == [super init]) { self.name = [aDecoder decodeObjectForKey:Name]; self.sex = [aDecoder decodeObjectForKey:Sex]; self.age = [[aDecoder decodeObjectForKey:Age] integerValue]; } return self; } - (void)encodeWithCoder:(NSCoder *)aCoder{ [aCoder encodeObject:self.name forKey:Name]; [aCoder encodeObject:self.sex forKey:Sex]; [aCoder encodeObject:[NSNumber numberWithInteger:self.age] forKey:Age]; } - (NSString *)description{ return [NSString stringWithFormat:@"%@--%@--%ld歲",self.name,self.sex,(long)self.age]; } @end
接下來只要使用解/歸檔輔助類就可以TestModel類進行解歸檔
//創建對象 並賦值
TestModel *model = [[TestModel alloc]init];
model.name = @"小明"; model.age = 25; model.sex = @"man"; //歸檔 NSMutableData *data = [[NSMutableData alloc] init]; //創建歸檔輔助類 NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; //編碼 [archiver encodeObject:model forKey:@"model"]; //結束編碼 [archiver finishEncoding]; //寫入到沙盒 NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *fileName = [array.firstObject stringByAppendingPathComponent:@"archiverModel"]; if([data writeToFile:fileName atomically:YES]){ NSLog(@"歸檔成功"); } //解檔 NSData *undata = [[NSData alloc] initWithContentsOfFile:fileName]; //解檔輔助類 NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:undata]; //解碼並解檔出model TestModel *unModel = [unarchiver decodeObjectForKey:@"model"]; NSLog(@"%@",unModel); //關閉解檔 [unarchiver finishDecoding];
運行代碼之后 打印
4.手動存放沙盒
iphone沙箱模型的有四個文件夾,分別是documents,tmp,app,Library。
1、Documents 目錄:您應該將所有的應用程序數據文件寫入到這個目錄下。這個目錄用於存儲用戶數據或其它應該定期備份的信息。為了不讓App的備份過於龐大,我們不建議在這里存放大容量的文件。
2、AppName.app 目錄:這是應用程序的程序包目錄,包含應用程序的本身。由於應用程序必須經過簽名,所以您在運行時不能對這個目錄中的內容進行修改,否則可能會使應用程序無法啟動。
3、Library 目錄:這個目錄下有兩個子目錄:Caches 和 Preferences
Preferences 目錄:包含應用程序的偏好設置文件。您不應該直接創建偏好設置文件,而是應該使用NSUserDefaults類來取得和設置應用程序的偏好.
Caches 目錄:用於存放應用程序專用的支持文件,保存應用程序再次啟動過程中需要的信息。細心的話你會發現幾乎所有的第三方框架的緩存信息處理都在這個文件中,一般的大容量文件都放在這里。
4、tmp 目錄:這個目錄用於存放臨時文件,保存應用程序再次啟動過程中不需要的信息。Nsuserdefaults保存的文件一般在tmp文件夾里。
獲取這些目錄路徑的方法:
1,獲取家目錄路徑的函數:
NSString *homeDir = NSHomeDirectory();
2,獲取Documents目錄路徑的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
3,獲取Caches目錄路徑的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDir = [paths objectAtIndex:0];
4,獲取tmp目錄路徑的方法:
NSString *tmpDir = NSTemporaryDirectory();
沙盒中只能保存OC中的基本數據,自定義的對象不能直接存入。 存入方式如下。
// 1,獲取家目錄路徑的函數:
// NSString *homeDir = NSHomeDirectory();
// 2,獲取Documents目錄路徑的方法:
// NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// NSString *docDir = [paths objectAtIndex:0];
// 3,獲取Caches目錄路徑的方法:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDir = [paths objectAtIndex:0]; // 4,獲取tmp目錄路徑的方法: // NSString *tmpDir = NSTemporaryDirectory(); //假設我們需往cache 存入數據,並命名為test的txt格式文件中 NSString *filePath = [cachesDir stringByAppendingPathComponent:@"test.txt"]; NSArray *dic = [[NSArray alloc] initWithObjects:@"test",@"test1" ,nil]; if([dic writeToFile:filePath atomically:YES]){ NSLog(@"存入成功"); } //取出數據 打印 NSLog(@"%@",[NSArray arrayWithContentsOfFile:filePath]);
打印如圖:
在下一篇文中將介紹使用數據庫Sqlite。