国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

IOS開發-數據庫總結

2019-11-14 20:01:35
字體:
來源:轉載
供稿:網友

關于數據存儲概念:

數據結構:

  •  基本對象:NSDictionary、NSArray和NSSet這些對象。
  •  復雜對象:關系模型、對象圖和屬性列表多種結構等。

存儲方式:

  • 內存:內存存儲是臨時的,運行時有效的,但效率高。
  • 閃存:閃存則是一種持久化存儲,但產生I/O消耗,效率相對低。

歸檔:把內存數據轉移到閃存中進行持久化的操作的過程。

常用的數據存儲方案:

  • 屬性列表:NSArray、NSDictionary、NSData、NSString、NSNumber、NSDate等

        基本數據類型都支持這個機制,NSUserDefaults 也屬于屬性列表存儲,常用

        于存儲配置信息。這個機制可以將這些對象直接序列化到 plist 文件中,多用

        于少量數據的存儲,效率較高。

simple code:

    // NSUserDefaults 默認    NSUserDefaults *userDefaults =  [NSUserDefaults standardUserDefaults];    [userDefaults setObject:@"skyming" forKey:@"username"];    [userDefaults setObject:[NSDate date] forKey:@"date"];    [userDefaults setObject:@[@"a1",@"a2"] forKey:@"array"];    [userDefaults setInteger:6174 forKey:@"code"];    NSLog(@"userDefaults: %@",[userDefaults dictionaryRePResentation]);        NSString *username = [userDefaults objectForKey:@"username"];    NSDate *date = [userDefaults objectForKey:@"date"];    NSArray *array = [userDefaults objectForKey:@"array"];    NSInteger code = [userDefaults integerForKey:@"code"];        NSLog(@"username: %@  date:%@  /n array: %@ code: %d", username, date, array, code);    [userDefaults synchronize];    // NSUserDefaults 自定義    NSUserDefaults *defaults = [[NSUserDefaults alloc] init];    [defaults setPersistentDomain:[NSDictionary dictionaryWithObject:@"Hello" forKey:@"World"] forName:@"com.Sensoro.DefaultsTest"];    [defaults synchronize];//  數組    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);      NSString *docPath = [paths objectAtIndex:0];      NSString *myFile = [docPath stringByAppendingPathComponent:@"my.list"];      //讀取文件      NSArray *array = [[NSArray alloc] initWithContentsOfFile:myFile];      //操作完若修改了數據則,寫入文件      [array writeToFile:myFile atomically:YES];  

 

  • 對象歸檔: 自定義對象常用的存儲機制,對象必須實現 NSCoding 協議,NSCopying協議可選

simple code

 #pragma mark -#pragma NSCoding協議實現實現- (void)encodeWithCoder:(NSCoder *)aCoder{   //encoder    [aCoder encodeObject:self.username forKey:@"username"];    [aCoder encodeObject:self.passWord forKey:@"password"];}- (id)initWithCoder:(NSCoder *)aDecoder{    //decoder    if (self = [super init]) {        self.username = [aDecoder decodeObjectForKey:@"username"];        self.password =  [aDecoder decodeObjectForKey:@"password"];    }    return self;}#pragma NSCopying協議實現- (id)copyWithZone:(NSZone *)zone{    DSObj *copy = [[[self class] allocWithZone:zone] init];    return copy;}// 讀取        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);    NSString *docPath = [paths objectAtIndex:0];    NSString *myFile = [docPath stringByAppendingPathComponent:@"dsObj.list"];        //寫入歸檔文件    NSMutableData *datawrite = [[NSMutableData alloc] init];    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:datawrite];    [archiver encodeObject:test forKey:@"data"];    [archiver finishEncoding];    [datawrite writeToFile:myFile atomically:YES];        //讀取歸檔文件    NSData *data = [[NSMutableData alloc] initWithContentsOfFile:myFile];    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];    DSObj *testread = [unarchiver decodeObjectForKey:@"data"];    [unarchiver finishDecoding];    NSLog(@"DSObjRead: %@ %@",[testread username], [testread password]);

當屬性多時總不能一個個的添加吧,個人偏向于使用基于運行時的一個方案:

需要歸檔的對象只需要繼承即可。

鏈接: https://github.com/skyming/SSObjectBase

 

  • SQLite: 用于存儲查詢需求較多的數據  

iOS的SDK里預置了SQLite3的庫,開發者可以自建SQLite數據庫。SQLite每次寫入數據

都會產生IO消耗,把數據歸檔到相應的文件。SQLite擅長處理的數據類型其實與NSUser-

Defaults差不多,也是基礎類型的小數據,只是從組織形式上不同。開發者可以以關系型

數據 庫的方式組織數據,使用SQL DML來管理數據。一般來說應用中的格式化的文本類

數據可以存放在數據庫中,尤其是類似聊天記錄、Timeline等這些具有條件查詢和排序需

求的數據。每一個數據庫的句柄都會在內存中都會被分配一段緩存,用于提高查詢效率。

另一個方面,由于查詢緩存,當產生大量句柄或數據量較大時,會出現緩存過大,造成

內存浪費。

simple code

//open database- (void)openDataBase{    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);    NSString *docPath = [paths objectAtIndex:0];    NSString *myFile = [docPath stringByAppendingPathComponent:@"data.db"];        if (sqlite3_open([myFile UTF8String], &database)==SQLITE_OK)    {        NSLog(@"open sqlite db ok.");    }    else    {        NSLog( @"can not open sqlite db " );                //close database        sqlite3_close(database);    }}//create table- (void)createTable{    char *errorMsg;    const char *createSql="create table if not exists persons (id integer primary key autoincrement,name text)";        if (sqlite3_exec(database, createSql, NULL, NULL, &errorMsg)==SQLITE_OK)    {        NSLog(@"create ok.");    }    else    {        NSLog( @"can not create table" );        [self ErrorReport:[NSString stringWithFormat:@"%s",createSql]];    }}//insert table- (void)insertTable{    char *errorMsg;        const char *insertSql="insert into persons (name) values ('skyming')";    if (sqlite3_exec(database, insertSql, NULL, NULL, &errorMsg)==SQLITE_OK)    {        NSLog(@"insert ok.");    }    else    {        NSLog( @"can not insert it to table" );        [self ErrorReport:[NSString stringWithFormat:@"%s",insertSql]];    }}//query table- (void)queryTable{    const char *selectSql="select id,name from persons";    sqlite3_stmt *statement;    if (sqlite3_prepare_v2(database, selectSql, -1, &statement, nil)==SQLITE_OK)    {        NSLog(@"select ok.");        while (sqlite3_step(statement)==SQLITE_ROW)//SQLITE_OK SQLITE_ROW        {            int _id=sqlite3_column_int(statement, 0);            NSString *name=[[NSString alloc] initWithCString:(char *)sqlite3_column_text(statement, 1) encoding:NSUTF8StringEncoding];            NSLog(@"row>>id %i, name>> %@",_id,name);        }            }    else    {        //error        [self ErrorReport:[NSString stringWithFormat:@"%s",selectSql]];    }        sqlite3_finalize(statement);}//delete table- (void)deleteTable{    char *errorMsg;    [self openDataBase];        const char *sql = "DELETE FROM persons where id=24";    if (sqlite3_exec(database, sql, NULL, NULL, &errorMsg)==SQLITE_OK)    {        NSLog(@"delete ok.");    }    else    {        NSLog( @"can not delete it" );        [self ErrorReport:[NSString stringWithFormat:@"%s",sql]];    }    }//error- (void)ErrorReport: (NSString *)item{    char *errorMsg;        if (sqlite3_exec(database, [item cStringUsingEncoding:NSUTF8StringEncoding], NULL, NULL, &errorMsg)==SQLITE_OK)    {        NSLog(@"%@ ok.",item);    }    else    {        NSLog(@"error: %s",errorMsg);        sqlite3_free(errorMsg);    }}

 

SQLite的使用起來要比NSUserDefaults復雜的多,因此建議開發者使用SQLite要

搭配一個操作控件使用,可以簡化操作。gaosboy 開發的SQLight是一款對SQLit

e操作的封裝,把相對復雜的SQLite命令封裝成對象和方法,可以供大家參考。

鏈接地址:https://github.com/gaosboy/SQLight

Github 星比較多的方案:FMDB

鏈接地址:https://github.com/ccgus/fmdb

  • CoreData,用于規劃應用中的對象

官方給出的定義是,一個支持持久化的,對象圖和生命周期的自動化管理方案。嚴格

意義上說CoreData是一個管理方案,他的持久化可以通過 SQLite、xml或二進制

文件儲存。如官方定義所說,CoreData的作用遠遠不止儲存數據這么簡單,它可以

把整個應用中的對象建模并進行自動化的 管理。

上圖,官方文檔中解釋CoreData給出的對象圖示例

正如上圖所示,MyDocument是一個對象實例,有兩個Collection:Employee和

Department,存放各自的對象列表。 MyDocument、Employee和Department

三個對象以及他們之間的關系都通過CoreData建模,并可以通過save方法進行持久

化。從歸檔文件還原模型時CoreData并不是一次性把整個模型中的所有數據都載入

內存,而是根據運行時狀態,把被調用到的對象實例載入內存。框架會自動控制這個

過程,從而達到控制內存消耗,避免浪費。無論從設計原理還是使用方法上看,Core-

Data都比較復雜。因此,如果僅僅是考慮緩存數據這個需求,CoreData絕對不是一個

優選方案。 CoreData的使用場景在于:整個應用使用CoreData規劃,把應用內的數

據通過CoreData建模,完全基于CoreData架構應用。蘋果官方給出的一個示例代碼,

結構相對簡單,可以幫助大家入門CoreData。

鏈接地址:

http://developer.apple.com/library/ios/

  • 使用基本對象類型定制的個性化緩存方案

之前提到的NSUserDefaults和SQLite適合存儲基礎類型的小數據,而CoreData則不適合

存儲單一的數據,那么對于類似圖片這 種較大的數據要用什么方式儲存呢?gaosboy 給出

的建議就是:自己實現一套存儲方案。首先要明確,這個所謂的定制方案適用于互聯網應用

中對遠程數據的緩存,幾個限制條件缺一不可。從需求出發分析緩存數據有哪些要求:按Key

查找,快速讀取,寫入不影響正常操作,不浪費內存,支持歸檔。這些都是基本需求,那么再

進一步或許還需 要固定緩存項數量,支持隊列緩存,緩存過期等。從這些需求入手設計一個

緩存方案并不十分復雜,Kache是筆者根據開發應用的需求開發的一套緩存組件,通 過分析

Kache希望可以給大家一個思路。

 

如上圖所示,Kache扮演的是一個典型緩存角色。應用加載遠程數據生成應用數據

對象的同時,通過Kache把數據緩存起來,再次請求則直接通過Kache獲取數據。

緩存對象可以是NSDictionary、NSArray、NSSet或NSData這些可直接歸檔的類型,

每個緩存對象對應一個Key。緩存對象 包括數據和過期時間,內存中存放在一個單例

字典中,閃存中每個對象存為一個文件。Key空間按照各種順序存放緩存對象的Key集

合,Pool為固定大小的 數組,當數量達到上限,最早過期的一個Key將被刪除,對應的

緩存對象也被清除。Queue也是固定大小的數組,以先進先出的規則管理Key的增刪。

每一次有新的緩存對象存入,自動檢測Key空間中過期的集合并清除。此外,控件提供

save和load方法支持持久化和重新載入。Kache最初設計為存放圖片緩存,之后也曾用

于緩存文本數據,由于使用了過期和歸檔相結合的邏輯,可以保證大部分命中的緩存對象

都在內存中,從而獲取了較高的效率。讀者可以從Github上獲取Kache源碼了解更多。

以上介紹了幾種iOS開發中經常會遇到的儲存數據方法,從其存儲原理、使用方式和適用

場景幾方面進行進了簡單的對比。事實上每一款應用都很難采用一種單一的方案完成整個

應用的數據儲存任務,需要根據不同的數據類型,選擇最合適的方案,以便整個應用獲得

良好的運行時性能。

 
simpleCode代碼
相關鏈接:
 
 
 
 
 
 
 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 兴仁县| 香河县| 锦州市| 盈江县| 南部县| 三台县| 香河县| 额尔古纳市| 囊谦县| 桃江县| 游戏| 盐城市| 揭西县| 惠东县| 合江县| 泸定县| 孝感市| 丰县| 顺义区| 九寨沟县| 呼玛县| 元江| 泰州市| 平阴县| 油尖旺区| 玉溪市| 怀安县| 浏阳市| 稻城县| 潼南县| 乳源| 东乡族自治县| 景德镇市| 上思县| 牙克石市| 青浦区| 仙桃市| 犍为县| 犍为县| 达州市| 图们市|