日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ios序列化与反序列化,本地化

發布時間:2025/1/21 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ios序列化与反序列化,本地化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

你是用什么方法來持久保存數據的?這是在幾乎每一次關于iOS技術的交流或討論都會被提到的問題,而且大家對這個問題的熱情持續高漲。本文主要從概念上把“數據存儲”這個問題進行剖析,并且結合各自特點和適用場景給大家提供一個選擇的思路,并不詳細介紹某一種方式的技術細節。

談到數據儲存,首先要明確區分兩個概念,數據結構和儲存方式。所謂數據結構就是數據存在的形式。除了基本的NSDictionary、NSArray和NSSet這些對象,還有更復雜的如:關系模型、對象圖和屬性列表多種結構。而存儲方式則簡單的分為兩種:內存與閃存。內存存儲是臨時的,運行時有效的,但效率高,而閃存則是一種持久化存儲,但產生I/O消耗,效率相對低。把內存數據轉移到閃存中進行持久化的操作稱成為歸檔。

二者結合起來才是完整的數據存儲方案,我們最常談起的那些:SQLite、CoreData、NSUserDefaults等都是數據存儲方案。當然在這些框架提供的方案之外,我們自己也可以按照個性化需求訂制方案。這些存儲方案側重不同,支持的形式和方式也各不相同,在不同的使用場景下表現也是各有優劣。但萬變不離其宗,無論什么方案都可以用下圖來解釋。

圖1,存儲方案示意圖

以下將對四種存儲方式進行詳細的介紹:

  • NSUserDefaults,用于存儲配置信息

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

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

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

NSUserDefaults存儲配置信息

NSUserDefaults被設計用來存儲設備和應用的配置信息,它通過一個工廠方法返回默認的、也是最常用到的實例對象。這個對象中儲存了系統中用戶的配置信息,開發者可以通過這個實例對象對這些已有的信息進行修改,也可以按照自己的需求創建新的配置項。

圖2,筆者手機中[NSUserDefaults standardUserDefaults]內容

NSUserDefaults把配置信息以字典的形式組織起來,支持字典的項包括:字符串或者是數組,除此之外還支持數字等基本格式。一句話概括就是:基礎類型的小數據的字典。操作方法幾乎與NSDictionary的操作方法無異,另外還可以通過指定返回類型的方法獲取到指定類型的返回值。

圖3,NSUserDefaults提供的指定返回類型的方法列表

NSUserDefaults的所有數據都放在內存里,因此操作速度很快,并還提供一個歸檔方法:+ (void)synchronize。開發者自定義的配置項(如圖2中的最后一項 key:alkdjfkladsjfmm)會以plist格式的文件歸檔在相應應用目錄的/Library/Preferences/[App_Bundle_Identifier].plist文件。再次初始化獲得實例對象后,框架會把用戶自定義的這個配置和系統配置合并得到完整數據。

SQLite存儲查詢需求較多的數據

iOS的SDK里預置了SQLite的庫,開發者可以自建SQLite數據庫。SQLite每次寫入數據都會產生IO消耗,把數據歸檔到相應的文件。

SQLite擅長處理的數據類型其實與NSUserDefaults差不多,也是基礎類型的小數據,只是從組織形式上不同。開發者可以以關系型數據庫的方式組織數據,使用SQL DML來管理數據。 一般來說應用中的格式化的文本類數據可以存放在數據庫中,尤其是類似聊天記錄、Timeline等這些具有條件查詢和排序需求的數據。

每一個數據庫的句柄都會在內存中都會被分配一段緩存,用于提高查詢效率。另一個方面,由于查詢緩存,當產生大量句柄或數據量較大時,會出現緩存過大,造成內存浪費。

SQLite的使用起來要比NSUserDefaults復雜的多,因此建議開發者使用SQLite要搭配一個操作控件使用,可以簡化操作。筆者開發的SQLight是一款對SQLite操作的封裝,把相對復雜的SQLite命令封裝成對象和方法,可以供大家參考。大家可以在Github上獲取這個工程的代碼進一步了解。

CoreData規劃應用中對象

官方給出的定義是,一個支持持久化的,對象圖和生命周期的自動化管理方案。嚴格意義上說CoreData是一個管理方案,他的持久化可以通過SQLite、XML或二進制文件儲存。如官方定義所說,CoreData的作用遠遠不止儲存數據這么簡單,它可以把整個應用中的對象建模并進行自動化的管理。

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

正如上圖所示,MyDocument是一個對象實例,有兩個Collection:Employee和Department,存放各自的對象列表。MyDocument、Employee和Department三個對象以及他們之間的關系都通過CoreData建模,并可以通過save方法進行持久化。

從歸檔文件還原模型時CoreData并不是一次性把整個模型中的所有數據都載入內存,而是根據運行時狀態,把被調用到的對象實例載入內存。框架會自動控制這個過程,從而達到控制內存消耗,避免浪費。

無論從設計原理還是使用方法上看,CoreData都比較復雜。因此,如果僅僅是考慮緩存數據這個需求,CoreData絕對不是一個優選方案。CoreData的使用場景在于:整個應用使用CoreData規劃,把應用內的數據通過CoreData建模,完全基于CoreData架構應用。

蘋果官方給出的一個示例代碼,結構相對簡單,可以幫助大家入門CoreData。

obj-c中有一類對象:NSArray,NSDictionary,NSString,NSNumber,NSDate,NSData以及它們的可變版本(指NSMutableArray,NSMutableDictionary...這一類) ,都可以方便的將自身的數據以某種格式(比如xml格式)序列化后保存成本地文件。



示例代碼:NSArrayTest.h

#import?<Foundation/Foundation.h> #define?FILE_NAME?@"/tmp/data.txt"@interface?NSArrayTest?:?NSObject?{?? }-(void)?Test;@end #import?"NSArrayTest.h"@implementation??NSArrayTest-(void)?Test {NSArray?*arr?=?[NSArray?arrayWithObjects:@"one",@"two",@"three",nil];??????//注:最后一個要以nil結尾[arr?writeToFile:FILE_NAME?atomically:YES];?????????//(序列化為xml格式后)保存文件NSArray?*arr2?=?[NSArray?arrayWithContentsOfFile:FILE_NAME];?????????//read?fileNSLog(@"%@",arr2);}@end


運行結果:NSArrayTest.m

2011-03-03 14:20:01.501 pList[1246:a0f] (
??? one,
??? two,
??? three
)

如果查看/tmp/data.txt,能看到下面的內容:

<?xml?version="1.0"?encoding="UTF-8"?> <!DOCTYPE?plist?PUBLIC?"-//Apple//DTD?PLIST?1.0//EN"?"http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist?version="1.0"> <array><string>one</string><string>two</string><string>three</string> </array> </plist>

即NSArray默認是以xml格式來序列化對象的.

如果你用來存放數據的類是自己定義的,并不是上面這些預置的對象,那么就要借助正式協議NSCoding來實現序列化和反序列化。


比如,我們有一個自己的類Sample.h

#import?<Foundation/Foundation.h>@interface?Sample?:?NSObject<NSCoding>?{NSString*?name;int?magicNumber;float?shoeSize;NSMutableArray?*subThingies; }@property(copy)?NSString*?name; @property?int?magicNumber; @property?float?shoeSize; @property?(retain)?NSMutableArray?*subThingies;-(id)?initWithName:(NSString?*)n?magicNumber:(int)m?shoeSize:(float)?ss;@end

這里我們定義幾個不同類型的屬性,有字符串,有整數,有浮點數,還有一個可變長的數組對象

Sample.m

#import?"Sample.h"@implementation?Sample@synthesize?name; @synthesize?magicNumber; @synthesize?shoeSize; @synthesize?subThingies;-(id)?initWithName:(NSString?*)n?magicNumber:(int)m?shoeSize:(float)ss {if?(self=[super?init]){self.name?=?n;self.magicNumber?=?m;self.shoeSize?=?ss;self.subThingies?=?[NSMutableArray?array];}return?(self); }-(void)?dealloc {[name?release];[subThingies?release];[super?dealloc]; }//將對象編碼(即:序列化) -(void)?encodeWithCoder:(NSCoder?*)aCoder {[aCoder?encodeObject:name?forKey:@"name"];[aCoder?encodeInt:magicNumber?forKey:@"magicNumber"];[aCoder encodeFloat:shoeSize?forKey:@"shoeSize"];[aCoder encodeObject:subThingies?forKey:@"subThingies"]; }//將對象解碼(反序列化) -(id)?initWithCoder:(NSCoder?*)aDecoder {if?(self=[super?init]){self.name?=?[aDecoder?decodeObjectForKey:@"name"];self.magicNumber?=?[aDecoder?decodeIntForKey:@"magicNumber"];self.shoeSize?=?[aDecoder?decodeFloatForKey:@"shoeSize"];self.subThingies?=?[aDecoder?decodeObjectForKey:@"subThingies"];}return?(self);}-(NSString*)?description {NSString?*description?=?[NSString?stringWithFormat:@"%@:%d/%.1f?%@",name,magicNumber,shoeSize,subThingies];return?(description); }@end

注意其中的:encodeWithCoderinitWithCoder,這是NSCoding協議中定義的二個方法,用來實現對象的編碼與解碼。其實現也不復雜,利用的是key-value的經典哈希結構。當然一般在編碼中,對于key的名字字符串,建議用define以常量方式事先定義好,以避免開發人員字符串鍵入錯誤。

測試一下:

#import?<Foundation/Foundation.h> #import?"Sample.h"int?main?(int?argc,?const?char?*?argv[])?{NSAutoreleasePool?*?pool?=?[[NSAutoreleasePool?alloc]?init]; Sample?*s1?=?[[Sample?alloc]?initWithName:@"thing1"?magicNumber:42?shoeSize:10.5]; [s1.subThingies?addObject:@"1"];[s1.subThingies?addObject:@"2"];NSLog(@"%@",s1); NSData *data1?=?[NSKeyedArchiver?archivedDataWithRootObject:s1];//將s1序列化后,保存到NSData中[s1?release];[data1?writeToFile:@"/tmp/data.txt"?atomically:YES];//持久化保存成物理文件NSData?*data2?=?[NSData?dataWithContentsOfFile:@"/tmp/data.txt"];//讀取文件 Sample?*s2?=?[NSKeyedUnarchiver?unarchiveObjectWithData:data2];//反序列化 NSLog(@"%@",s2);[pool?drain];return?0; }

運行結果:

2011-03-03 14:36:48.540 pList[1322:a0f] thing1:42/10.5 (
??? 1,
??? 2
)
2011-03-03 14:36:48.548 pList[1322:a0f] thing1:42/10.5 (
??? 1,
??? 2
)

查看/tmp/data.txt,能看到以下內容:

由于經過了編碼,里面的內容沒有象前面的NSArray那樣可讀性強。


有關序列化和反序列化內容轉自如下地址:

http://www.cnblogs.com/yjmyzz/archive/2011/03/03/1969859.html


轉載于:https://my.oschina.net/sayonala/blog/305624

總結

以上是生活随笔為你收集整理的ios序列化与反序列化,本地化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。