iOS 持久化: Objective-C 和 Xamarin.iOS-Monotouch 的 NSCoding 已翻译 100%

oschina 投递于 2013/10/18 10:43 (共 4 段, 翻译完成于 10-20)
阅读 816
收藏 0
0
加载中

介绍

应用存储数据。由于无可非议,因为它涉及一份声明。如何在不同的平台上存储数据保持长的效果涉及和经常无聊的谈话,如果在回来的路上数落我和我的同事嘻嘻哈哈,无所事事。

然而iOS库能使数据保存的非常简单,所以,它很好。如果你使用objective-c,数据对象能实现NScoding协议和允许本机库保存并加载数据对象。Montouch稍微需要一个不同的路径,但大多数步骤是相当类似的。两者之间应该是简单直接的。一旦实现这些方法,我们可以使用NSKeyedArchiver和NSKeyedUnarchiver对象保存和加载我们的数据。

crossmix
翻译于 2013/10/18 17:21
1

Object-C和NSCoding协议

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"];
如果这个版本有变,我们可以在解码器中处理那个版本数字,但这个问题我们日后再谈吧。
yale8848
翻译于 2013/10/19 11:10
1

那么在对数据进行编码后我们就可以进行持久化处理了。在保存时,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要好。事实上,从上面的示例代码中可以看出来。
yale8848
翻译于 2013/10/19 11:26
1

Monotouch和NSCoder

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的输出。

再瞧瞧,容易吧,小伙伴们!

yale8848
翻译于 2013/10/19 22:29
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(0)

返回顶部
顶部