1. 程式人生 > >IOS的四種資料儲存方式及優劣

IOS的四種資料儲存方式及優劣

IOS有四種常用資料儲存方式:
第一種方法:用NSUserDefaults儲存配置資訊
NSUserDefaults被設計用來儲存裝置和應用的配置資訊,它通過一個工廠方法返回預設的、也是最常用到的例項物件。這個物件中儲存了系統中使用者的配置資訊,開發者可以通過這個例項物件對這些已有的資訊進行修改,也可以按照自己的需求建立新的配置項。他實際上是儲存於檔案沙盒中的一個.plist檔案,並且沒有被系統加密,只是ios6以後不是存於常用的文件目錄下,所以不破解系統是看不到該檔案的。所以該種方法儲存的資料並不是很很安全,若想儲存安全還是靠你自己的加密演算法。一般這種方法儲存少量資訊,若是儲存大量資訊,如儲存一百個資料你怎麼記錄鍵值啊?它可以在程式碼的任何部分儲存資料,你不知道你整個應用儲存了多少資料,所以它不利於統一管理,不建議採用。就是你把儲存資料的函式統一放在一個檔案中便於管理,但是你不能保證別人也遵循你的意志與做法啊,所以最好用第二種物件儲存比較好。所有的機密資料都儲存在一個物件中,一看就知道了,刪除和新增很方便,便於管理。作為合格的碼農,別說那麼多應該和不該是,業務邏輯決定不會有這樣的資料這樣蒼白的話,要從機制上杜絕各種異常資料。如:物件儲存,在所有函式入口對引數進行合法性判斷。

+ (void)setUserDefaultsValue:(id)value key:(NSString *)key
{
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

    [userDefaults setObject:value forKey:key];
    [[NSUserDefaults standardUserDefaults] synchronize];

}

+ (id)objectForKey:(NSString *)key
{
    return [[NSUserDefaults
standardUserDefaults] objectForKey:key]; }

呼叫:
NSString *selectedKey = [[NSUserDefaults standardUserDefaults] objectForKey:@”selectedKey”];

第二種方法:方法用CoreData物件儲存。像MFC等稱之為序列化和反序列化,MFC是實際上存於應用對應的資料庫表單中。他實際上是把檔案存在檔案沙盒中,對應的是文件目錄,所以使用者可以看到該檔案,系統對該檔案進行了加密。一般檔名的字尾是.archiver。這樣對那些不想設計加密演算法,又想加密資料的人是個不錯的福音。
一個支援持久化的,物件圖和生命週期的自動化管理方案。它的資料也是存於系統資料庫中應用對應的表中,所以可以用於儲存機密資料(如:使用者名稱和密碼),可以儲存各種資料。一般超大的資料,如:圖片,行程記錄存在檔案沙盒中,不適合用這種物件儲存,除非你的行程資料很機密,並且資料不可能超大,才考慮物件儲存。嚴格意義上說CoreData是一個管理方案,他的持久化可以通過SQLite、XML或二進位制檔案儲存。如官方定義所說,CoreData的作用遠遠不止儲存資料這麼簡單,它可以把整個應用中的物件建模並進行自動化的管理。他和微軟的MFC::CArchive實現物件的持久化和反持久化一樣只能支援支援具有序列化的函式,把物件分解成基本資料型別的型別的持久化,如字串,整形數字,浮點型資料,字元。由於持久化的物件資料都在一個物件中,所以他利於資料管理。所以採用CoreData儲存資料就不需要採用NSUserDefaults資料儲存資料了。
-(id)initWithDictionary:(NSDictionary*)dic
{
if (self=[super init])
{
self.sex=[dic[@”sex”] intValue];
self.driverYear=[dic[@”driverYear”] intValue];
}

return self;

}

-(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:[NSNumber numberWithInt:self.driverId] forKey:@”id”];
[aCoder encodeObject:[NSNumber numberWithInt:self.sex] forKey:@”sex”];

}
-(id)initWithCoder:(NSCoder *)aDecoder
{
if (self=[super init])
{
self.sex=[[aDecoder decodeObjectForKey:@”sex”] intValue];
self.driverYear=[[aDecoder decodeObjectForKey:@”driverYear”] intValue];
}
return self;
}

//清理使用者資訊
- (void)clearUserInfo{
    NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *path = [documents stringByAppendingPathComponent:@"user.archiver"];
    User *user;
    [NSKeyedArchiver archiveRootObject:user toFile:path];
}

//儲存
-(void)saveinfo:(User *)user
{
    if(nil != user)
    {
        NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        NSString *path = [documents stringByAppendingPathComponent:@"user.archiver"];
        [NSKeyedArchiver archiveRootObject:user toFile:path];
    }
}

//得到使用者資訊
-(User *)getUserinfo;
{
    NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *path = [documents stringByAppendingPathComponent:@"user.archiver"];//拓展名可以自己隨便取
    User *user = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    return user;
}

//從物件沙盒中讀檔案
        User*user=[[GlobalShare getGlobalShare] getUserinfo];

        [GlobalShare getGlobalShare].user = user;
        [GlobalShare getGlobalShare].user.orderLastLatitude = 0;
   // 儲存在本地
       [[GlobalShare getGlobalShare] saveinfo:user];

第三種方法:檔案沙盒儲存
主要儲存非機密資料,大的資料。如:下載的圖片,沒有鍵值的分行記錄。注意若系統被破解了你的沙盒中的檔案可以被別人獲得。這種方法操作很簡單。不知道為何很多介紹資料儲存的文章為何把這種最常見的,最簡單直接的方式給忽略了。檔案沙盒常用的檔案一般儲存於文件檔案目錄(NSDocumentDirectory非破解系統,使用者可以直接看到)和快取文件目錄(NSCachesDirectory非破解系統,使用者不可見)。看來天下文章一大抄啊!
//寫檔案
+ (void)writeToDocumentWithImageData:(NSData )data name:(NSString )fileName
{
NSString *path = [self filePath:fileName];

[data writeToFile:path atomically:YES];

}
//獲取檔案路徑
+ (NSString*)filePath:(NSString*)fileName {
NSArray* myPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString* myDocPath = [myPaths objectAtIndex:0];
NSString* filePath = [myDocPath stringByAppendingPathComponent:fileName];
return filePath;
}
第四種方法:資料庫儲存
iOS的SDK裡預置了SQLite的庫,開發者可以自建SQLite資料庫。SQLite每次寫入資料都會產生IO消耗,把資料歸檔到相應的檔案。
SQLite擅長處理的資料型別其實與NSUserDefaults差不多,也是基礎型別的小資料,只是從組織形式上不同。開發者可以以關係型資料庫的方式組織資料,使用SQL DML來管理資料。 一般來說應用中的格式化的文字類資料可以存放在資料庫中,尤其是類似聊天記錄、Timeline等這些具有條件查詢和排序需求的資料。
無論你採用系統自帶的還是用的SQLight第三方庫的資料儲存本質都資料庫儲存,沒必要再另外分類。資料儲存稍微麻煩,並且儲存的速度較慢,只有真正需要用到的地方才採用這種方式,如:聊天記錄,地圖地理資訊查詢。