iPhone存儲相關技術-待續

1,NSKeyedArchiver(加密形式):

代碼如下:

//=================NSKeyedArchiver========================
NSString *saveStr1 = @"我是";
NSString *saveStr2 = @"數據";
NSArray *array = [NSArray arrayWithObjects:saveStr1, saveStr2, nil];

//----1,Save保存
//這一句是將路徑和文件名合成文件完整路徑
NSString *Path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filename = [Path stringByAppendingPathComponent:@"saveDatatest"];
[NSKeyedArchiver archiveRootObject:array toFile:filename];

//用於測試是否已經保存了數據
saveStr1 = @" ";
saveStr2 =@" ";

//----2,restore恢復
array = [NSKeyedUnarchiver unarchiveObjectWithFile: filename];
saveStr1 = [array objectAtIndex:0];
saveStr2 = [array objectAtIndex:1];

2,NSUserDefaults:
//=================NSUserDefaults========================
NSString *saveStr1 = @"我是";
NSString *saveStr2 = @"數據";
NSArray *array = [NSArray arrayWithObjects:saveStr1, saveStr2, nil];
//1,Save保存之
NSUserDefaults *saveDefaults = [NSUserDefaults standardUserDefaults];
[saveDefaults setObject:array forKey:@"SaveKey"];
//用於測試是否已經保存了數據
saveStr1 = @" ";
saveStr2 =@" ";

//---2,restore恢復
array = [saveDefaults objectForKey:@"SaveKey"];
saveStr1 = [array objectAtIndex:0];
saveStr2 = [array objectAtIndex:1];
3,Write寫入方式:
//=================Write寫入方式========================
NSString *saveStr1 = @"我是";
NSString *saveStr2 = @"數據";
NSArray *array = [NSArray arrayWithObjects:saveStr1, saveStr2, nil];

//----1,Save保存之
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
if(!documentsDirectory) {
    NSLog(@"沒找到");
}
NSMutableArray *saveDataArray=nil;
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:@"Savedatas.plist"];
[[NSArray arrayWithObjects:array,nil] writeToFile:appFile atomically:NO];

//用於測試是否已經保存了數據
saveStr1 = @" ";
saveStr2 =@" ";

//----2,restore恢復之
if([[NSFileManager defaultManager] fileExistsAtPath:appFile]){
    saveDataArray = [NSMutableArray arrayWithContentsOfFile:appFile];
} else{
    saveDataArray = [NSMutableArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Savedatas"ofType:@"plist"]];
}
NSArray *strArray = [saveDataArray objectAtIndex:0];
saveStr1 = [strArray objectAtIndex:0];
saveStr2 = [strArray objectAtIndex:1];
附:

對於取出數據的時候需要注意,例如如下代碼:

NSUserDefaults *saveDefaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *arraySaveData =[saveDefaults objectForKey:@"OhSaveData"];
//NSMutableArray *arraySaveData=[NSMutableArray arrayWithArray:[saveDefaults objectForKey:@"OhSaveData"]];

第二句代碼是通過一個文件名獲取你存儲的數據,返回數據數組,但是!一定要注意這裏返回的數據數組是不可修改的!及時你將讀取的數據賦給一個可修改的數組中也一樣無法修改其中的數據,所以如果你想將取出的數據進行修改那麼這裏需要要使用第三行代碼來獲取,這裏Himi將獲取出的數據數組首先copy給了可修改數組中,那麼此時你的可修改數組就可以正常修改了!

2.修改已經的存儲文件;代碼如下:

NSUserDefaults *saveDefaults = [NSUserDefaults standardUserDefaults];
[saveDefaults setObject:arraySaveData forKey:@"已經存在的文件名"];
原文地址:http://xiaominghimi.blog.51cto.com/2614927/709144
-----------------------------------------------------------------------------------------------------------------------------

copy 文件存儲小結

首選項設置存儲

NSUserDefaults 以及通過它控制的SettingBundle  NSUserDefaults 用來保存一些設置,他會自動寫到何時的位置。
NSUbiquitousKeyValueStore 多平臺同步設置,限制是大小64k,開啓entitlement,唯一Apple ID(還要考慮無法連接到iCloud網絡時的情形)

文件存儲
一.目錄描述
<Application_Home>/AppName.app bundle目錄,包括程序本身。往裏面些東西會導致簽名改變和重啓程序。初始同步後iTunes不備份此目錄。
<Application_Home>/Documents/ 存儲用戶文檔和程序數據。通過文件共享可以使其可見。iTunes備份之。
<Application_Home>/Documents/Inbox 其他程序要求本程序打開的文檔。可讀刪,不可增加修改。要改變可以先移出來。iTunes備份之。
<Application_Home>/Library/ 非用戶數據文件存儲的根目錄。用其中標準或自定義的文件夾備份不被用戶可見的數據。不應用這個目錄存儲用戶數據。iTunes備份之。
  ~Library/Application Support/<bundle_ID> 爲用戶創建管理的資源和數據文件。用這個目錄存儲程序狀態信息,下載的文件甚至用戶創建但同意你管理的數據。自動保存文件。
  ~/Library/Caches/<bundle_ID> 用來存儲緩存文件或者程序可以簡單重建的文件的目錄。
<Application_Home>/tmp/ 臨時文件目錄,可能被系統刪除,不應期望始終存在。不被iTunes備份。
另:

離線數據

可以下載,或重新創建,但用戶希望在離線時也能訪問這些數據。存放在<Application_Home>/Documents 或<Application_Home>/Library/Private Documents ,並標記爲"do not backup"。這兩個位置的數據在低存儲空間時都會保留,而"do not backup"屬性會阻止iTunes或iCloud備份。應用不再需要離線數據文件時,應該儘快刪除,以避免浪費用戶的存儲空間。

設置do not back up屬性

#include <sys/xattr.h>

- (BOOL)addSkipBackupAttributeToItemAtURL:(NSURL *)URL

{

    const char* filePath = [[URL path] fileSystemRepresentation];

 

    const char* attrName = "com.apple.MobileBackup";

    u_int8_t attrValue = 1;

 

    int result = setxattr(filePath, attrName, &attrValue, sizeof(attrValue), 0, 0);

    return result == 0;

}

 

得到目錄地址
URLsForDirectory:inDomains: method 返回NSURL形式的目錄地址
NSSearchPathForDirectoriesInDomains 返回字符串形式的目錄地址
NSHomeDirectory 返回程序根目錄
NSTemporaryDirectory 返回臨時文件目錄

相關變量定義

NSSearchPathDirectory
enum {
NSApplicationDirectory = 1,//Supported applications (/Applications)
NSDemoApplicationDirectory,//Unsupported applications and demonstration versions
NSDeveloperApplicationDirectory,//Developer applications (/Developer/Applications)
NSAdminApplicationDirectory,//System and network administration applications
NSLibraryDirectory,//Various user-visible documentation, support, and configuration files (/Library)
NSDeveloperDirectory,//Developer resources (/Developer)
NSUserDirectory,//User home directories (/Users)
NSDocumentationDirectory,//
NSDocumentDirectory,//
NSCoreServiceDirectory,//Location of core services (System/Library/CoreServices)
NSAutosavedInformationDirectory = 11,//Location of user’s autosaved documents Library/Autosave Information
NSDesktopDirectory = 12,//
NSCachesDirectory = 13,//Location of discardable cache files (Library/Caches)
NSApplicationSupportDirectory = 14,//Location of application support files (Library/Application Support)
NSDownloadsDirectory = 15,//
NSInputMethodsDirectory = 16,//
NSMoviesDirectory = 17,//
NSMusicDirectory = 18,//
NSPicturesDirectory = 19,//
NSPrinterDescriptionDirectory = 20,//
NSSharedPublicDirectory = 21,//
NSPreferencePanesDirectory = 22,//
NSItemReplacementDirectory = 99,//
NSAllApplicationsDirectory = 100,//
NSAllLibrariesDirectory = 101//
};
typedef NSUInteger NSSearchPathDirectory;

enum {
NSUserDomainMask = 1,//用戶主目錄中
NSLocalDomainMask = 2,//當前機器中
NSNetworkDomainMask = 4,//網絡中可見的主機
NSSystemDomainMask = 8,//系統目錄,不可修改(/System)
NSAllDomainsMask = 0x0ffff,//全部
};
typedef NSUInteger NSSearchPathDomainMask;

二.存儲方式

(一).屬性列表(plist)
array,dictionary,data,string,NSNumber,NSDate 等ns對象直接寫入plist文件中保存.
(二).歸檔文件
實現NSCoding協議(NSCopy也要實現?沒實現也成功了。。)

編解碼類說明

NSKeyedArchiver

創建
- (id)initForWritingWithMutableData:(NSMutableData *)data // 歸檔數據寫到data中
歸檔數據
+ (NSData *)archivedDataWithRootObject:(id)rootObject // 歸檔到data中
+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path // 歸檔到文件中
- (void)finishEncoding // 調用後不能繼續歸檔數據,歸檔結束必須調用(公共方法歸檔的不用理這個了)
– outputFormat // data編碼方式,xml還是二進制
– setOutputFormat:
編碼數據
– encodeBool:forKey:
– encodeBytes:length:forKey:
– encodeConditionalObject:forKey:
– encodeDouble:forKey:
– encodeFloat:forKey:
– encodeInt:forKey:
– encodeInt32:forKey:
– encodeInt64:forKey:
– encodeObject:forKey:
代理委託
– delegate
– setDelegate:

– archiver:didEncodeObject:
– archiverDidFinish:
– archiver:willEncodeObject:
– archiverWillFinish:
– archiver:willReplaceObject:withObject:

類和類名
+ setClassName:forClass:
+ classNameForClass:
– setClassName:forClass:
– classNameForClass:
異常
extern NSString *NSInvalidArchiveOperationException;

NSKeyedUnarchiver

創建
– initForReadingWithData:
取消歸檔
+ (id)unarchiveObjectWithData:(NSData *)data // 從data中得到實現歸檔的對象
+ (id)unarchiveObjectWithFile:(NSString *)path // 從文件中得到
解碼數據
- (BOOL)containsValueForKey:(NSString *)key // 是否包含給定的key編碼對象
– decodeBoolForKey:
– decodeBytesForKey:returnedLength:
– decodeDoubleForKey:
– decodeFloatForKey:
– decodeIntForKey:
– decodeInt32ForKey:
– decodeInt64ForKey:
– decodeObjectForKey:
- (void)finishDecoding // 通知委託解碼結束,調用後不能再繼續解碼
代理委託
– delegate
– setDelegate:

– unarchiver:cannotDecodeObjectOfClassName:originalClasses:
– unarchiver:didDecodeObject:
– unarchiver:willReplaceObject:withObject:
Finishing Decoding
– unarchiverDidFinish:
– unarchiverWillFinish:

類名
+ setClass:forClassName:
+ classForClassName:
– setClass:forClassName:
– classForClassName:
異常
NSString *NSInvalidUnarchiveOperationException;


(三).CoreData
xcdatamodeld文件中Entity的三種屬性:
Attributes: 對應的Obj-c類的接口變量.
Relationships: Entity之間的關係,to-one,or to-many.
Fetched properties: 對上面Relationship的過濾?參考參考1

對應文件存儲形式

COREDATA_EXTERN NSString * const NSSQLiteStoreType NS_AVAILABLE(10_4, 3_0);// SQLite形式存儲
COREDATA_EXTERN NSString * const NSXMLStoreType NS_AVAILABLE(10_4, NA);// ios不可用
COREDATA_EXTERN NSString * const NSBinaryStoreType NS_AVAILABLE(10_4, 3_0);// 二進制形式存儲
COREDATA_EXTERN NSString * const NSInMemoryStoreType NS_AVAILABLE(10_4, 3_0);// 內存中

基本使用過程(括號中參考sql術語)
NSManagedObjectModel對象 獲取工程中xcdatamodeld文件設置的模版(就是你的數據庫有哪些表,表中有哪些字段的一種說明)
NSPersistentStoreCoordinator對象 根據上面的模版生成或對應的一個文件(數據庫文件,具體的數據文件)
NSManagedObjectContext對象 上面文件的操作的空間,增刪改查都通過這裏進行
NSEntityDescription對象 得到上面context中的一個表
NSFetchRequest對象 對上面表的一些具體操作,增刪改查
- (NSArray *)executeFetchRequest:(NSFetchRequest *)request error:(NSError **)error; 使用這個方法執行上面的request
如果增刪改了context,記得保存。結束

過程示例:

NSManagedObjectContext *managedObjectContext = nil;
// 得到模版
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"YOUR_XCDATAMODELD_FILE_NAME" withExtension:@"momd"];
NSManagedObjectModel* managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
// 具體文件,DOCUMENT_DICRECTORY應該是nsurl的..
NSURL *storeURL = [@"DOCUMENT_DICRECTORY" URLByAppendingPathComponent:@"SQLITE.sqlite"];
NSError *error = nil;
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel];
// 使用SQLite存儲
if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {

// 出錯

else
{
// 得到操作空間
managedObjectContext = [[NSManagedObjectContext alloc] init];
[managedObjectContext setPersistentStoreCoordinator:coordinator];
}

// 得到具體的表
NSEntityDescription *entityDescription = [NSEntityDescription
entityForName:@"ONE_ENTITY_NAME"
inManagedObjectContext:managedObjectContext];
// 操作語句
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
// 操作語句的條件
NSPredicate *pred = [NSPredicate predicateWithFormat:@"PREDICATE_SECTION"];
[request setPredicate:pred];

NSManagedObject *manageObject = nil;
// 執行操作,得到多條具體數據
NSArray *objects = [managedObjectContext executeFetchRequest:request error:&error];

if (objects == nil) {
// 出錯

}
if ([objects count] > 0)
// 多條,取第一條
manageObject = [objects objectAtIndex:0];
else
// 沒有相應的,就創建
manageObject = [NSEntityDescription
insertNewObjectForEntityForName:@"TABLE_NAME"
inManagedObjectContext:managedObjectContext];
// 改變她的一個字段的值 
[manageObject setValue:@"VALUE" forKey:@"ONE_FIELD_NAME_OF_THE_TABLE"];

[request release];
// 保存,結束
[managedObjectContext save:&error];


(四).SQLite
引入SQLite庫,加入頭文件,使用C API操作.繁瑣的地方在於只能存儲c數據格式,需要來回轉換.

過程示例:

// 聲明數據庫
sqlite3 *database;
// 打開
if (sqlite3_open("數據庫文件路徑", &database) != SQLITE_OK) {
sqlite3_close(database);
// 出錯
}

char *errorMsg;
// 執行無返回語句
if (sqlite3_exec (database, "增刪改創語句",NULL, NULL, &errorMsg) != SQLITE_OK) {
sqlite3_close(database);
// 出錯
}
sqlite3_stmt *statement;
// 執行查詢語句
if (sqlite3_prepare_v2(database, "查詢語句",-1, &statement, nil) == SQLITE_OK) {
// 遍歷結果
while (sqlite3_step(statement) == SQLITE_ROW) {
int row = sqlite3_column_int(statement, 0);
// 第一列數據
char *rowData = (char *)sqlite3_column_text(statement, 1);
}
// 結束遍歷
sqlite3_finalize(statement);
}
// 關閉數據庫
sqlite3_close(database);

參考1:http://stackoverflow.com/questions/2985054/what-exactly-is-a-fetched-property


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章