智汇工业-智慧工业、智能制造及工业智能、工业互联门户网站,专业的工业“互联网+”传媒

深入理解iPhone數(shù)據(jù)持久化

來(lái)源:網(wǎng)絡(luò)

點(diǎn)擊:1350

A+ A-

所屬頻道:新聞中心

關(guān)鍵詞: iPhone,數(shù)據(jù)持久化,開(kāi)發(fā)

      在所有的移動(dòng)開(kāi)發(fā)平臺(tái)數(shù)據(jù)持久化都是很重要的部分:在j2me中是rms或保存在應(yīng)用程序的目錄中,在symbian中可以保存在相應(yīng)的磁盤(pán)目錄中和數(shù)據(jù)庫(kù)中。symbian中因?yàn)闄?quán)限認(rèn)證的原因,在3rd上大多數(shù)只能訪問(wèn)應(yīng)用程序的private目錄或其它系統(tǒng)共享目錄。在iphone中,apple博采眾長(zhǎng),提供了多種數(shù)據(jù)持久化的方法,下面筆者會(huì)逐個(gè)進(jìn)行詳細(xì)的講解。

      iphone提供的數(shù)據(jù)持久化的方法,從數(shù)據(jù)保存的方式上講可以分為三大部分:屬性列表、對(duì)象歸檔、嵌入式數(shù)據(jù)庫(kù)(SQLite3)、其他方法。

      一、屬性列表NSUserDefaults

      NSUserDefaults類的使用和NSKeyedArchiver有很多類似之處,但是查看NSUserDefaults的定義可以看出,NSUserDefaults直接繼承自NSObject而NSKeyedArchiver 繼承自NSCoder。這意味著NSKeyedArchiver實(shí)際上是個(gè)歸檔持久化的類,也就可以使用NSCoder類的[encodeObject: (id)objv forKey:(NSString *)key]方法來(lái)對(duì)數(shù)據(jù)進(jìn)行持久化存儲(chǔ)。

      - (void)applicationDidFinishLaunching:(UIApplication *)application {

      NSString *strOne = @“Persistent data1”;

      NSString *strTwo = @“Persistent data 2”;

      NSMutableArray *persistentArray = [[NSMutableArray alloc] init];

     ?。踦ersistentArray addObject:strOne];

     ?。踦ersistentArray addObject:strTwo];

      //archive

      NSUserDefaults *persistentDefaults = [NSUserDefaults standardUserDefaults];

     ?。踦ersistentDefaults setObject:persistentArray forKey:@“myDefault”];

      NSString *descriptionDefault = [persistentDefaults description];

      NSLog(@“NSUserDefaults description is :%@”,descriptionDefault);

      //unarchive

      NSArray *UnpersistentArray =

     ?。踦ersistentDefaults objectForKey:@“myDefault”];

      NSString *UnstrOne = [UnpersistentArray objectAtIndex:0];

      NSString *UnstrTwo = [UnpersistentArray objectAtIndex:1];

      NSLog(@“UnstrOne = %@,UnstrTwo = %@”,UnstrOne,UnstrTwo);

      // Override point for customization after application launch

      [window makeKeyAndVisible];

      }

      二、對(duì)象歸檔NSKeyedArchiver和NSKeyedUnarchiver

      iPhone和symbian 3rd一樣,會(huì)為每一個(gè)應(yīng)用程序生成一個(gè)私有目錄,這個(gè)目錄位于

      /Users/sundfsun2009/Library/Application Support/iPhone Simulator/User/Applications下,并隨即生成一個(gè)數(shù)字字母串作為目錄名,在每一次應(yīng)用程序啟動(dòng)時(shí),這個(gè)字母數(shù)字串都是不同于上一次的,上一次的應(yīng)用程序目錄信息被轉(zhuǎn)換成名為.DS_Store隱藏文件,這個(gè)目錄的文件結(jié)構(gòu)如下圖:

      通常使用Documents目錄進(jìn)行數(shù)據(jù)持久化的保存,而這個(gè)Documents目錄可以通過(guò)NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserdomainMask,YES)得到,代碼如下:

      - (void)applicationDidFinishLaunching:(UIApplication *)application {

      NSString *strOne = @“Persistent data1”;

      NSString *strTwo = @“Persistent data 2”;

      NSArray *persistentArray = [NSArray arrayWithObjects:strOne,strTwo,nil];

      NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSAllDomainsMask, YES);

      int pathLen = [pathArray count];

      NSLog(@“path number is :%d”,pathLen);

      NSString *filePath;

      for(int i = 0; i 《 pathLen; i++)

      {

      filePath = [pathArray objectAtIndex:i];

      NSLog(@“%d path is :%@”,i,filePath);

      }

      NSString *myFilename = [filePath stringByAppendingPathComponent:@“myFile.rtf”];

      NSLog(@“myfile‘s path is :%@”,myFilename);

      // no files generated in correspond directory now

     ?。跱SKeyedArchiver archiveRootObject:persistentArray toFile:myFilename];

      // now the myFile.rtf is generated

      // Override point for customization after application launch

     ?。踳indow makeKeyAndVisible];

      }

      NSSearchPathForDirectoriesInDomains()的第二個(gè)參數(shù)是個(gè)枚舉值,在筆者的測(cè)試代碼中,只有NSUserDomainMask和NSAllDomainsMask可以獲取到目錄數(shù)為1,其余的皆為0,打印出來(lái)的結(jié)果如下:

      [Session started at 2009-11-10 21:30:08 +0800.]

      2009-11-10 21:30:10.516 PersistentExample[763:207] path number is :1

      2009-11-10 21:30:10.518 PersistentExample[763:207] 0 path is :/Users/sundfsun2009/Library/Application Support/iPhone Simulator/User/Applications/C93DC783-F137-4660-AE5A-08C3E11C774B/Documents

      2009-11-10 21:30:10.521 PersistentExample[763:207] myfile’s path is :/Users/sundfsun2009/Library/Application Support/iPhone Simulator/User/Applications/C93DC783-F137-4660-AE5A-08C3E11C774B/Documents/myFile.rtf

      Terminating in response to SpringBoard‘s termination.

     ?。跾ession started at 2009-11-10 21:32:27 +0800.]

      2009-11-10 21:32:30.091 PersistentExample[803:207] path number is :1

      2009-11-10 21:32:30.092 PersistentExample[803:207] 0 path is :/Users/sundfsun2009/Library/Application Support/iPhone Simulator/User/Applications/763E6772-E754-452F-8532-80C2CE4466B5/Documents

      2009-11-10 21:32:30.100 PersistentExample[803:207] myfile’s path is :/Users/sundfsun2009/Library/Application Support/iPhone Simulator/User/Applications/763E6772-E754-452F-8532-80C2CE4466B5/Documents/myFile.rtf

      Terminating in response to SpringBoard‘s termination.

      從打印的結(jié)果如下,每次應(yīng)用程序啟動(dòng)時(shí)生成的數(shù)字字母串目錄名字并不一樣。在調(diào)用[NSKeyedArchiver archiveRootObject:persistentArray toFile:myFilename]方法前,文件myFile.rtf并每生成,只有在調(diào)用此方法后才產(chǎn)生相應(yīng)的文件。

      下面需要把數(shù)據(jù)從屬性列表中讀取出來(lái),在上面的代碼中,筆者使用NSArray保存數(shù)據(jù)。但在大多數(shù)應(yīng)用程序中,數(shù)據(jù)的尺寸并不是固定的,這個(gè)時(shí)候就需要使用NSMutalbeArray動(dòng)態(tài)的保存數(shù)據(jù),代碼優(yōu)化如下:

      - (void)applicationDidFinishLaunching:(UIApplication *)application {

      NSString *myFilename;

      // archive

      {

      NSString *strOne = @“Persistent data1”;

      NSString *strTwo = @“Persistent data 2”;

      NSMutableArray *persistentArray = [[NSMutableArray alloc] init];

      [persistentArray addObject:strOne];

     ?。踦ersistentArray addObject:strTwo];

      NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSAllDomainsMask, YES);

      int pathLen = [pathArray count];

      NSLog(@“path number is :%d”,pathLen);

      NSString *filePath;

      for(int i = 0; i 《 pathLen; i++)

      {

      filePath = [pathArray objectAtIndex:i];

      NSLog(@“%d path is :%@”,i,filePath);

      }

      myFilename = [filePath stringByAppendingPathComponent:@“myFile.rtf”];

      NSLog(@“myfile’s path is :%@”,myFilename);

      [NSKeyedArchiver archiveRootObject:persistentArray toFile:myFilename];

      }

      // unarchive

      {

      NSArray *unarchiveArray = [NSKeyedUnarchiver unarchiveObjectWithFile:myFilename];

      NSString *UnstrOne = [unarchiveArray objectAtIndex:0];

      NSString *UnstrTwo = [unarchiveArray objectAtIndex:1];

      NSLog(@“UnstrOne = %@,UnstrTwo = %@”,UnstrOne,UnstrTwo);

      }

      // Override point for customization after application launch

     ?。踳indow makeKeyAndVisible];

      }

      輸出結(jié)果如下:

     ?。跾ession started at 2009-11-10 22:41:57 +0800.]

      2009-11-10 22:41:59.344 PersistentExample[1082:207] path number is :1

      2009-11-10 22:41:59.346 PersistentExample[1082:207] 0 path is :/Users/sundfsun2009/Library/Application Support/iPhone Simulator/User/Applications/055CD17C-864E-4A83-ABF0-5F01EE85BD5A/Documents

      2009-11-10 22:41:59.355 PersistentExample[1082:207] myfile‘s path is :/Users/sundfsun2009/Library/Application Support/iPhone Simulator/User/Applications/055CD17C-864E-4A83-ABF0-5F01EE85BD5A/Documents/myFile.rtf

      2009-11-10 22:41:59.357 PersistentExample[1082:207] UnstrOne = Persistent data1,UnstrTwo = Persistent data 2

      Terminating in response to SpringBoard’s termination.

      從上面的圖中可以看到,目錄中還有個(gè)tmp目錄,讀者也可以把數(shù)據(jù)保存在tmp目錄中,獲取這個(gè)目錄使用NSTemporaryDirectory()方法。

      三、嵌入式數(shù)據(jù)庫(kù)(SQLite3)

      嵌入式數(shù)據(jù)庫(kù)持久化數(shù)據(jù)就是把數(shù)據(jù)保存在iphone的嵌入式數(shù)據(jù)庫(kù)系統(tǒng)SQLite3中,本質(zhì)上來(lái)說(shuō),數(shù)據(jù)庫(kù)持久化操作是基于文件持久化基礎(chǔ)之上的。

      要使用嵌入式數(shù)據(jù)庫(kù)SQLite3,首先需要加載其動(dòng)態(tài)庫(kù)libsqlite3.dylib,這個(gè)文件位于/Xcode3.1.4/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/usr/lib目錄下。在Framework文件夾上右擊,選擇“Adding-》Existing Files.。.”,定位到上述目錄并加載到文件夾。

      首先在頭文件中做如下修改:

      #import 《UIKit/UIKit.h》

      #include “sqlite3.h”

      #define kFileName @“mydb.sql”

      @interface PersistentExampleAppDelegate : NSObject 《UIApplicationDelegate》 {

      sqlite3 *database;

      UIWindow *window;

      }

      @property (nonatomic, retain) IBOutlet UIWindow *window;

      @end

      - (void)applicationDidFinishLaunching:(UIApplication *)application {

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

      NSString *paths = [[path objectAtIndex:0] stringByAppendingPathComponent:kFileName];

      NSFileManager *fileManager = [NSFileManager defaultManager];

      BOOL findFile = [fileManager fileExistsAtPath:paths];

      NSLog(@“Database file path = %@”,paths);

      // 如果找到了數(shù)據(jù)庫(kù)文件

      if(findFile)

      {

      NSLog(@“Database file have already existed.”);

      if(sqlite3_open([paths UTF8String], &database) != SQLITE_OK)//打開(kāi)數(shù)據(jù)庫(kù)失敗

      {

      sqlite3_close(database);

      NSAssert(0,@“Failed to open database”);

      }

      }else

      {

      NSLog(@“Database file does not exsit!”);

      if(sqlite3_open([paths UTF8String], &database) != SQLITE_OK)//打開(kāi)數(shù)據(jù)庫(kù)失敗

      {

      sqlite3_close(database);

      NSAssert(0,@“Failed to open database”);

      }

      }

      char *errorMsg;

      //創(chuàng)建表

      NSString *createSQL = @“create table if not exists fields (row integer primary key, field_data text);”;

      if(sqlite3_exec(database, [createSQL UTF8String],NULL,NULL,&errorMsg)!=SQLITE_OK)

      {

      sqlite3_close(database);

      NSAssert1(0,@“Error creating table: %s”,errorMsg);

      }

      NSString *strOne = @“Persistent data1”;

      NSString *strTwo = @“Persistent data 2”;

      NSMutableArray *persistentArray = [[NSMutableArray alloc] init];

     ?。踦ersistentArray addObject:strOne];

      [persistentArray addObject:strTwo];

      for (int i = 0; i 《 [persistentArray count]; i++) {

      NSString *upDataSQL = [[NSString alloc] initWithFormat:@“insert or replace into

      fields (row,field_data) values (%d,‘%@’);”,i,[persistentArray objectAtIndex:i]];

      char* errorMsg;

      if(sqlite3_exec(database,[upDataSQL UTF8String],NULL,NULL,&errorMsg)

     ?。? SQLITE_OK)

      {

      sqlite3_close(database);

      NSAssert(0,@“Failed to open database”);

      }

      }

      //unarchive

      NSString *query = @“select row, field_data from fields order by row”;//查找表中的數(shù)據(jù)

      sqlite3_stmt *statement;

      if(sqlite3_prepare_v2(database, [query UTF8String], -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);

      NSString *fieldName = [[NSString alloc] initWithFormat:@“show%d”,row];

      NSString *fieldValue = [[NSString alloc] initWithUTF8String:rowData];

      NSLog(@“fieldName is :%@,fieldValue is :%@”,fieldName,fieldValue);

      [fieldName release];

     ?。踗ieldValue release];

      }

      sqlite3_finalize(statement);

      }

      // Override point for customization after application launch

     ?。踳indow makeKeyAndVisible];

      }

      在上面的代碼中,我們使用

      NSFileManager *fileManager = [NSFileManager defaultManager];

      BOOL findFile = [fileManager fileExistsAtPath:paths];

      來(lái)判斷數(shù)據(jù)庫(kù)文件是否已經(jīng)存在,其實(shí)在大多數(shù)情況下是沒(méi)有必要的,sqlite3_open()方法會(huì)自動(dòng)幫我們判斷數(shù)據(jù)庫(kù)文件是否存在,如果不存在則創(chuàng)建心的數(shù)據(jù)庫(kù)文件。

      四、其它方法

      除了上面的三種方法來(lái)保存持久化數(shù)據(jù)以外,我們還可以用寫(xiě)文件到磁盤(pán)的方式來(lái)保存持久化數(shù)據(jù)。

      - (void)applicationDidFinishLaunching:(UIApplication *)application {

      NSString *strOne = @“Persistent data1”;

      NSString *strTwo = @“Persistent data 2”;

      NSMutableArray *persistentArray = [[NSMutableArray alloc] init];

     ?。踦ersistentArray addObject:strOne];

      [persistentArray addObject:strTwo];

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

      NSString *filePath =

      - [[filePathArray objectAtIndex:0] stringByAppendingPathComponent:@“mydatas.plist”];

      [[NSArray arrayWithObjects:persistentArray,nil] writeToFile:filePath atomically:NO];

      //load

      NSMutableArray *saveDataArray = [[NSMutableArray alloc] init];

      if([[NSFileManager defaultManager] fileExistsAtPath:filePath])

      saveDataArray = [NSMutableArray arrayWithContentsOfFile:filePath];

      else

      saveDataArray = [NSMutableArray arrayWithContentsOfFile:[[NSBundle

      - mainBundle] pathForResource:@“Savedatas” ofType:@“plist”]];

      -

      NSArray *strArray = [saveDataArray objectAtIndex:0];

      NSString *UnstrOne = [strArray objectAtIndex:0];

      NSString *UnstrTwo = [strArray objectAtIndex:1];

      // Override point for customization after application launch

     ?。踳indow makeKeyAndVisible];

      }

    (審核編輯: 智匯小新)

    聲明:除特別說(shuō)明之外,新聞內(nèi)容及圖片均來(lái)自網(wǎng)絡(luò)及各大主流媒體。版權(quán)歸原作者所有。如認(rèn)為內(nèi)容侵權(quán),請(qǐng)聯(lián)系我們刪除。

    主站蜘蛛池模板: 宁波宝新不锈钢有限公司| 污水处理控制系统设计_plc编程控制柜_电气成套设备生产厂家_合肥鸿昇自动化 | 水平转头微孔板离心机-米欧微孔板离心机-北京乾明基因技术 | 呕吐毒素快速检测仪-黄曲霉毒素测定仪-玉米赤霉烯酮快速检测卡-南京微测生物科技有限公司 | 新零售策划-全渠道策划-品牌营销全案策划-上海韬慧管理咨询有限公司 | 增压泵-离心泵-管道泵-排污泵-上海渤泉泵业制造有限公司 【官方网站】 | 搅拌设备_搅拌器_浓密机_浆式_顶入式_不锈钢「赛鼎机械」 | 太原门禁系统_太原车牌识别_山西人脸识别系统-山西元一智能科技有限公司 | 郑州井盖雨水篦子厂家-建联建材| 模温机_厂家_现货供应-卡塞尔机械(浙江)有限公司 | 人防信号控制箱厂家-液位控制器价格-信号灯箱批发厂家-消声加热器-鼎兴自控 | 饲料车_散装饲料车_畜禽运输车_散装饲料运输车_饲料车厂家_铝合金运猪车-程力专用汽车股份有限公司 | 拓展器材_拓展训练器械_心理行为训练器械_沧州华北特训器械有限公司 | 塑料植草格_停车场植草格_消防车道植草格厂家_山东朋联建材 | 苏子富春品牌馆 抚顺市富春农业科技开发有限公司 抚顺特色农产品 抚顺市特色馆 | 制冷设备|冷库|空调|配件【制冷通】国内领先的制冷服务平台 | 湖北大洋塑胶有限公司|AGR|PPR|RTP|HDPE|e-PSP钢塑复合压力管道生产厂家 | 停车场设计|地下停车场规划设计|智能停车位地下车库设计施工装修|深圳创安顺停车库规划设计有限公司 | 徐州护栏,围栏,锌铁丝网围栏安全设施专家徐州铜山区威峰金属护栏厂 | 润东方环保空调厂家-水冷式空调价格-润东方水冷空调-东莞市科骏机电设备有限公司 | 生物除臭剂-养殖场垃圾除臭剂-垃圾填埋场除臭剂-成都微菌环境 | 吸音板_隔音板多少钱_降噪声学材料_环保阻燃防火_吸声装饰工程定制_厂家价格直供 - 佛山天阶声学材料厂 | 热水工程|空气能热水工程|超低温采暖工程|太阳能热水工程|空气源热泵厂家|炬邦热能设备有限公司 热熔钻孔机【优质厂家】_多年热熔钻设备研发制造经验 | 医用手摇病床,医用电动病床,康养手摇病床,康养电动病床-河北丁丁医疗器械有限公司 | 辣椒烘干机-百信机械提供大中小型辣椒烘干机房设备视频图片厂家价格多少钱 | 中山电子控制板|中山工业控制板|中山市云禾电子科技有限公司 | 网架厂_网架加工厂家_徐州网架公司报价--三华网架制造商 | 无尘车间_洁净车间_净化车间_洁净室工程一站式净化服务商-深圳市美克威尔环境科技有限公司 | 太阳能路灯 太阳能路灯厂家 路灯厂家-保定正联光电科技有限公司 太阳能光伏发电_太阳能热水器_空气能热水器_直饮净水器_深圳市大兴节能环保科技有限公司 | 慢直播摄像头厂家,监控直播摄像机厂家,景区慢直播设备,rtmp推流直播摄像头,实时摄像头监控直播-监控慢直播厂家:专注监控慢直播系统解决方案 | 磨粉机_上海磨粉机_雷蒙磨粉机_超细磨粉机_磨粉机价格-上海山卓重工机械有限公司 | 石膏砂浆生产线_特种砂浆生产线_轻质抹灰石膏设备-青岛环港重工科技有限公司 | 输送机|滚筒输送机|皮带输送机|滚筒|无动力滚筒|万向球生产厂家-上海霞韵输送机械设备有限公司 | 新洲际教育-一站式留学解决方案领航者【官网】 | 上海千舟新材料有限公司-美卓隔膜滤板_奥图泰滤板_压滤机配件 | 威学一百-专注国际学校择校备考-DSE-A-level-雅思-托福-OSSD-港澳台联考-AP-IGCSE-IB-AMC-多邻国-PTE-SAT-SSAT-小语种(如日语,韩语,德语,法语,西班牙语,意大利语,俄语,泰语)等考试培训,为出国留学学生提供个性化定制性学习方案,线下实体面授+线上网络课程, 提供一对一,小班课等多种班型 | 山东优科机械设备有限公司,养鸡设备,湿帘设备,通风降温加湿设备,山东养鸡设备,山东湿帘设备 | 慧泊中安,慧眼停车,慧泊社区,慧泊云,智慧停车云平台 | 三菱PLC,三菱变频器,三菱伺服,三菱电机--广州凌控 | 耐磨涂料_陶瓷涂料_高温涂料_高硬度耐磨涂料-北京耐默科技 | 汽车配件加工生产模具-手板样品模型厂家-拓维模型 |