应用存储数据。由于无可非议,因为它涉及一份声明。如何在不同的平台上存储数据保持长的效果涉及和经常无聊的谈话,如果在回来的路上数落我和我的同事嘻嘻哈哈,无所事事。
然而iOS库能使数据保存的非常简单,所以,它很好。如果你使用objective-c,数据对象能实现NScoding协议和允许本机库保存并加载数据对象。Montouch稍微需要一个不同的路径,但大多数步骤是相当类似的。两者之间应该是简单直接的。一旦实现这些方法,我们可以使用NSKeyedArchiver和NSKeyedUnarchiver对象保存和加载我们的数据。
NSCoding是一个简单到只有两个方法就允许保存和加载数据的协议。
NSCoding有两个主要的部分
//进程保存对象状态时所调用的方法 -(void)encodeWithCoder:(NSCoder *)aCoder //在对象持久化过程中初始化调用 -(id)initWithCoder:(NSCoder *)aDecoder下面我给出一个实现了这个协议的数据类的例子。我们创建一个Book类,继承NSObject,并用NSCoding协议。
@interface Book : NSObject < NSCoding > @property int pageCount; @property NSString* title; @property Publisher* publisher; @end //我们用下面的方式实现这个类 @implementation Book -(void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:self.title forKey:@"title"]; [aCoder encodeInt:self.pageCount forKey:@"pageCount"]; [aCoder encodeObject:self.publisher forKey:@"publisher"]; } -(id)initWithCoder:(NSCoder *)aDecoder { self = [super init]; self.title = (NSString*)[aDecoder decodeObjectForKey:@"title"]; self.pageCount = [aDecoder decodeIntForKey:@"pageCount"]; self.publisher = (Publisher*)[aDecoder decodeObjectForKey:@"publisher"]; return self; } @end
这个类有3个属性,前两个是默认类型,最后一个是自定义数据类型将来要用。encodeWithCoder方法将接受一个对象参数来给属性赋值。传递一个字串键值用于将来检索。在这种情况下,我用属性名来作为键名,但这只是我个人的做法而已。因为我们可以控制“encode”方法,所以我们可以选择哪个属性可以保存以及怎样保存。同时,我们也可以在解码是保存额外的信息。比如,如果我们对一个版本数字进行编码
[aCoder encodeInt:1 forKey:@"version"];如果这个版本有变,我们可以在解码器中处理那个版本数字,但这个问题我们日后再谈吧。
那么在对数据进行编码后我们就可以进行持久化处理了。在保存时,iOS进程作为特殊的初始化器来重新创建对象。这个初始化动作就是initWithCoder。从上面的代码我们可以看出保存对象是很简单的,同时也很容易恢复。如果有必要,我们调用“decode”来释放NSCoder对象,然后我们的对象可以从存储里恢复。
用NSKeyedArcheiver和NSKeyedUnachiver可以让持久化神奇、完美和自动的发生。
NSData* _savedData; // to save data // the makeData method returns a NSMutableArray of book objects _savedData = [NSKeyedArchiver archivedDataWithRootObject:[self makeData]]; // to load data // Since we saved a NSMutableArray when we rehydrate we will get a populated array back NSMutableArray* bookData = (NSMutableArray*) [NSKeyedUnarchiver unarchiveObjectWithData:_savedData];之前说过我们可以在自定义对象里恢复持久化的数据。我们用支持NSCoding协议的对象比直接从父类调用encodObject要好。事实上,从上面的示例代码中可以看出来。
Monotouch在处理持久化时看起来是如此的熟悉,但不同的是它还需要更多的解释。我们没有直接用NSCoding协议。Monotouch而是提供了一个已被修改过并带有EncodeTo虚方法的NSObject,它同时也有一个额外的构造器可以很容易就能初始化。
那么就让我们来看看Book类在Monotouch中有什么不同
public class Book : NSObject { public int PageCount {get;set;} public string Title {get;set;} public Publisher Publisher {get;set;} public Book () { } [Export("initWithCoder:")] public Book(NSCoder coder) { this.PageCount = coder.DecodeInt (@"pageCount"); NSString str = (NSString)coder.DecodeObject (@"title"); if (str != null) { this.Title = str.ToString (); } this.Publisher = (Publisher) coder.DecodeObject ("publisher"); } public override void EncodeTo (NSCoder coder) { if (this.Title != null) coder.Encode (new NSString (this.Title), "title"); coder.Encode (this.PageCount, "pageCount"); if(this.Publisher!=null) coder.Encode (this.Publisher, "publisher"); }}
我们可以看出EncodeTo方法和Objective-C中的Encode方法类似。我不得不改变一些我的想法了。在Monotouch中我们可以用基本字串类型。当我们要保存数据时,我们需要将它们打包为NSString,这样在运行时刻就可以很容易的将数据持久化。另一个需要改变的我们需要添加额外的错误和空指针检查。但这没什么大不了的,是很容易做到的。
在解码阶段,我们要添加另一个构造器来作为initWithCoder的输出。
再瞧瞧,容易吧,小伙伴们!
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。 2KB翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务