当前位置:编程学习 > wap >>

归档自定义对象

Cocoa中,归档数据到文件,使用NSKeyedArchiver的archiveRootObject:toFile:方法。对于一般的数据类型(例如字符串),这个步骤是非常简单的。Apple官方文档中,这些数据类型包括:
 
    NSData
 
    NSString
 
    NSNumber
 
    NSDate
 
    NSArray
 
    NSDictionary
 
很显然,复杂数据例如UIImage,无法直接归档。但我们有一种变通的做法,先将UIImage对象转换为NSData,再对NSData进行归档。www.zzzyk.com
 
注1:准确地说,这依赖于iOS的版本。在iOS4中,UIImage未实现NSCoding协议,在iOS5中,UIImage实现了NSCoding协议。
 
对于自定义的类型,我们也可以参考这一做法,即先将将自定义类型转换为NSData,再对NSData进行归档。
 
问题在于,NSKeyedArchiver在归档一个自定义对象时,怎么知道如何将一个自定义对象编码为一个NSData?而且,当我们从文件中反归档时,NSKeyedUnarchiver怎么知道将NSData转变为一个自定义对象?
 
这就是NSCoding 协议需要解决的问题。实际上,NSCoding协议规定的两个方法,分别用于解决这两个问题。
 
当NSKeyedArchiver 在归档一个对象时,将调用对象的encodeWithCoder:方法,用于将对象转换为NSData(或NSString等其他5种类型);而NSKeyedUnarchiver在反归档一个对象时,则调用对象的initWithCoder:方法,用于将NSData(或NSString等其他5种类型)转换为指定的对象类型。
 
上述6种类型(NSData、NSString等)在归档/反归档时显得尤其简单,是因为苹果已经为我们实现了NSCoding协议。
 
而自定义对象不同,需要程序员自己实现其NSCoding协议。
 
新建项目,创建一个类MyClass,在头文件中声明对NSCoding协议的实现。
 
然后为他设计属性如下:
 
@interface MyClass : NSObject<NSCoding>
 
@property(strong,nonatomic)NSString* name;
 
@property(assign,nonatomic)int age;
 
@property(assign,nonatomic)BOOL sex;
 
@end
 
然后,在实现中实现NSCoding协议:
 
@implementation MyClass
 
@synthesize name,age,sex;
 
-(void)encodeWithCoder:(NSCoder *)encoder{
 
    [encoderencodeObject:self.name forKey:@"name"];
 
    [encoderencodeObject:[NSNumber numberWithInt: self.age] forKey:@"age"];
 
    [encoderencodeObject:[NSNumber numberWithBool: self.sex] forKey:@"sex"];
 
}
 
- (id)initWithCoder:(NSCoder *)decoder {
 
    if (self = [superinit]) {
 
       self.name = [decoder decodeObjectForKey:@"name"];
 
       self.age =((NSNumber*)[decoderdecodeObjectForKey:@"age"]).intValue;
 
       self.sex =((NSNumber*) [decoderdecodeObjectForKey:@"sex"]).boolValue;
 
    }
 
    return self;   
 
}
 
@end
 
在encodeWithCoder:方法中,这两句好像显得有点多余:
 
[encoder encodeObject:[NSNumber numberWithInt: self.age]forKey:@"age"];
 
[encoder encodeObject:[NSNumber numberWithBool: self.sex]forKey:@"sex"];
 
然而事实并不是这样的,encoder对象只能对已经实现了NSCoding的对象进行编码(即转换为6种类型之一),对于int、BOOL这样的简单类型则不行。因此,我们需要对age和sex属性转换为其他类型(6种类型之一),比如NSNumber。
 
同样,在initWithCoder:方法中,我们必须对decoder反编码后的数据进行必要的转换,将它们由NSNumber(因为编码时我们是用NSNumber存储的)转换为相应属性原来的类型,才能进行赋值:
 
self.age =((NSNumber*)[decoderdecodeObjectForKey:@"age"]).intValue;
 
self.sex =((NSNumber*) [decoder decodeObjectForKey:@"sex"]).boolValue;
 
接下来,我们使用NSKeyedArchiver/NSKeyedUnarchiver来对MyClass进行归档/反归档。
 
打开ViewController.xib,设计如下UI界面:
 
 
\
 
 
使用Asistant Editor,创建必要的连接。这时ViewController.h文件内容将显示如下:
 
#import "MyClass.h"
 
#define AppDocuments [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0]
 
@interface ViewController : UIViewController<UITextFieldDelegate>
 
@property (retain, nonatomic) IBOutlet UITextField *tfName;
 
@property (retain, nonatomic) IBOutlet UITextField *tfAge;
 
@property (retain, nonatomic) IBOutlet UISegmentedControl *segSex;
 
@property (retain, nonatomic) IBOutlet UIButton *button;
 
- (IBAction)archiveUnarchive:(id)sender;
 
@end
 
在ViewDidLoad方法中,加入语句
 
[self initUI:nil];
 
其中,initUI:方法定义如下:
 
-(void)initUI:(MyClass*)obj{
 
    if (obj==nil) {
 
       tfName.text=nil;
 
       tfAge.text=nil;
 
       segSex.selectedSegmentIndex=0;
 
}else{
 
       tfName.text=obj.name;
 
       tfAge.text=[NSString stringWithFormat:@"%d",obj.age];
 
       segSex.selectedSegmentIndex=obj.sex;
 
}
 
}
 
定义方法makeMyClassInstance,在这个方法中我们通过用户在界面是输入的内容创建MyClass实例:
 
-(MyClass*)makeMyClassInstance{
 
    MyClass*obj=[[MyClass alloc]init];
 
   obj.name=tfName.text;
 
    obj.age=[tfAge.textintValue];
 
    obj.sex=[segSexselectedSegmentIndex]!=0;
 
    return [objautorelease];
 
}
 
定义按钮事件的Action方法如下:
 
- (IBAction)archiveUnarchive:(id)sender {
 
   button.enabled=NO;
 
    NSString*filePath=[AppDocuments stringByAppendingPathComponent:@"customobject.txt"];
 
    if(button.tag==0) {
 
       if (tfName && tfName.text.length>0 && tfAge&& tfAge.text.length>0) {
 
           button.tag=1;
 
           [button setTitle:@"反归档" forState:UIControlStateNormal];
 
           My
补充:移动开发 , IOS ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,