App開發流程之資料持久化和編譯靜態連結庫,app靜態

來源:互聯網
上載者:User

App開發流程之資料持久化和編譯靜態連結庫,app靜態

先記錄資料持久化。

iOS用戶端提供的常用資料持久化方案:NSUserDefaults代表的使用者佈建,NSKeydArchiver代表的歸檔,plist檔案儲存體,SQLite資料庫(包括上層使用的Core Data,FMDB)。

每種方案都有各自的應用情境和範圍,不能一概而論。不過可以大致以資料儲存量和複雜度來區別。

除了以上提到的方案,再記錄一種方案:LevelDB代表的索引值對資料庫。

 

NSUserDefaults常用方法:

1.可以使用標準使用者佈建[NSUserDefaults standardUserDefaults],也可以通過init相關方法初始化新的使用者佈建

2.像使用字典一樣擷取、設定、移除索引值對

3.synchronize方法已經不建議使用

 

Plist檔案儲存體:

1.代碼讀取應用內已經存在的plist檔案,得到一個字典

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"plist"];

    NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];

2.修改資料後,儲存或者建立plist檔案

    [dic writeToFile:filePath atomically:YES];

 

NSKeydArchiver和NSKeyedUnarchiver:

1.歸檔有一個類方法:+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;

   解檔有一個類方法:+ (nullable id)unarchiveObjectWithFile:(NSString *)path;

 可以直接對某一個對象進行歸檔和解檔。

2.但如果需要對多個索引值對進行操作,建議使用如下方法:

+ (void)archiveDataWithDictionary:(NSDictionary *)dic filename:(NSString*)filename archiveSuccessBlock:(archiveSuccessBlock)archiveSuccessBlock{    NSString *fullPath = [self getAppArchivedFileFullPathWithName:filename];        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        NSMutableData *data = [NSMutableData data];        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];                NSArray *keyArray = [NSArray arrayWithArray:[dic allKeys]];        [archiver encodeObject:keyArray forKey:filename];                for (NSString *key in keyArray) {            NSObject *object = [dic objectForKey:key];            [archiver encodeObject:object forKey:key];        }                [archiver finishEncoding];        [data writeToFile:fullPath atomically:YES];                if (archiveSuccessBlock) {            archiveSuccessBlock();        }    });}+ (NSDictionary *)unarchiveDataWithFilename:(NSString *)filename{    NSMutableDictionary *dic = [NSMutableDictionary dictionary];        NSData *data = [[NSData alloc] initWithContentsOfFile:[self getAppArchivedFileFullPathWithName:filename]];    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];        NSArray *keyArray = [NSArray arrayWithArray:[unarchiver decodeObjectForKey:filename]];        for (NSString *key in keyArray) {        NSObject *object = [unarchiver decodeObjectForKey:key];        [dic setObject:object forKey:key];    }        [unarchiver finishDecoding];    return dic;}

歸檔的initForWritingWithMutableData和finishEncoding,解檔的initForReadingWithData和finishDecoding需要成對出現。

 

SQLite資料庫:

只要使用過SQL Server和MySQL之類的關係型資料庫,就可以便於使用,只是底層的sql語言不太人性化,所以普遍採用了上層的Core Data或者FMDB類庫。

 

檔案操作:

首先關注方法:FOUNDATION_EXPORT NSArray<NSString *> *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde);第一個枚舉參數表示檔案目錄,第二個表示範圍域,第三個參數表示是否補充完整的相對路徑

1.得到目前使用者的doc檔案根目錄:

  NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *rootPath = paths[0];

2.補充子檔案路徑

    NSString *fullPath = [rootPath stringByAppendingPathComponent:filename];

3.檔案操作,主要使用[NSFileManager defaultManager]單例對象 

+ (void)createArchivedRootFile{    NSString *rootPath = [self getAppArchivedFilesRootPath];        if (![[NSFileManager defaultManager] fileExistsAtPath:rootPath]) {        [[NSFileManager defaultManager] createDirectoryAtPath:rootPath withIntermediateDirectories:YES attributes:nil error:nil];    }}+ (void)clearArchivedFileWithName:(NSString *)filename{    NSString *rootPath = [self getAppArchivedFilesRootPath];    NSString *fullPath = [rootPath stringByAppendingPathComponent:filename];        if ([[NSFileManager defaultManager] fileExistsAtPath:fullPath]) {        [[NSFileManager defaultManager] removeItemAtPath:fullPath error:nil];    }}

 

除了以上記錄方案,再記錄一下使用索引值對資料庫LevelDB的經曆。

當資料量並不是很大,但是又需要資料庫儲存和操作時候,索引值對資料庫是首選。源自Google的LevelDB是其中的明星。

之前遇到用戶端儲存省市區地址資料的需求,併當使用者選擇地址時候讀取相關資料。如果每次都完整讀取省市區資料,佔用記憶體既大又沒有必要,因為使用者很可能只會選擇一個省下的一個市的一個區。

如果將省市區資料拆分為若干索引值對,並且建立某種鏈式關係,就可以將資料以索引值對分散儲存於某個地方,並且快速讀取需要資料。

1.第一層級只有一個索引值對,key為固定值,value為全部省的名稱數組

2.第二層級索引值對數量為省數量,key為省名稱,value為市名稱數組

3.第三層級索引值對數量為市數量,key為“省名稱.市名稱”,value為區名稱數組

4.。。。。。

如上,資料全部以索引值對分散儲存於LevelDB中,只要知道key規則和名稱,就可以快速取到對應資料,而優秀的IO保證了效能表現。

這是之前記錄的一篇關於LevelDB的文章,可以先參考一下:http://www.cnblogs.com/A-Long-Way-Chris/p/4864573.html

 

編譯靜態連結庫

正好以LevelDB為案例。先前往下載C++原始碼: https://github.com/google/leveldb

使用Xcode建立靜態連結庫

1.建立項目,選擇類型

 

2.設定項目Build Phases,點擊地區左上方加號,選擇添加Headers Phase

 

3.點擊加號,添加需要公開暴露的標頭檔,然後從Project欄拖拽到Public欄

 

 

 4.切換真機和模擬器,分別編譯成功後,右鍵Products目錄下的libleveldb.a,在Finder中查看

 

5.在終端程式中cd到該目錄,輸入如下指令,即可匯出同時支援真機和模擬器啟動並執行靜態連結庫

lipo -create Debug-iphoneos/libleveldb.a Debug-iphonesimulator/libleveldb.a -output libleveldb.a 

 

使用命令列,通過Makefile編譯LevelDB的靜態連結庫

1.解壓下載包後,使用Visual Studio Code之類的文字編輯器開啟目錄下Makefile

2.修改Makefile中的CXXFLAGS,添加指令 -fembed-bitcode,儲存

 

3.在終端中,cd到LevelDB目錄,輸入指令:CXXFLAGS=-miphoneos-version-min=7.0 make PLATFORM=IOS

表示產生iOS版本的靜態連結庫,支援最低版本為7.0(該設定保證在模擬器上可以正常運行)。

如果提示permission denied,則在上述指令前加上sudo,最終為:sudo CXXFLAGS=-miphoneos-version-min=7.0 make PLATFORM=IOS,然後輸入密碼斷行符號即可。

 

 4.說明一下,如果跳過步驟1和2,最後產生的LevelDB靜態連結庫不支援bitcode,可以看到體積相差還是比較大的,按需編譯

 

將.a檔案和include目錄下的標頭檔加入項目即可正常使用。

1.如果遇到提示某標頭檔找不到,請檢查項目配置中,Header Search Paths是否有配置缺失

2.如果使用不支援bitcode的版本,需要在build setting中將enable bitcode設定為NO。該設定對其他類庫要求一樣

 

為了便於使用OC編程,還引入了另一個類庫,對LevelDB的代碼進行了OC封裝,地址:https://github.com/matehat/Objective-LevelDB

 

我在base項目中,增加了LevelDBHelper工具類,進一步對調用代碼進行了封裝,操作更簡單安全。

 

base項目已更新:git@github.com:ALongWay/base.git

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.