黑马程序员技术交流社区

标题: 详解Objective-C归档问题解决 [打印本页]

作者: 602516169    时间: 2016-8-28 07:01
标题: 详解Objective-C归档问题解决
Objective-C归档问题解决是本文要将诶少的内容,主要是来学习在Objective-C如何来归档,本文很详细的解决了这一问题,来看详细内容。

对于基本Objective-C类对象(NSString,NSArray...):

方法一:使用XML属性列表进行归档。

代码

NSDictionary *glossay;   
//存   
  glossay = [NSDictionary dictionaryWithObjectsAndKeys:@"obj val 1",@"key1",@"obj val 2",@"key2",nil];   
if ([glossay writeToFile:@"glossary" atomically:YES] == NO) {   
   NSLog(@"Save to file failed!");   
}   
//取   
glossay = [NSDictionary dictionaryWithContentsOfFile:@"glossary"];  
NSLog(@"%@",[glossay valueForKey:@"key2"]);
方法二:使用NSKeyedArchiver归档。

代码

NSDictionary *glossay;   
glossay = [NSDictionary dictionaryWithObjectsAndKeys:@"obj val 1",@"key1",@"obj val 2",@"key2",nil];   
//存   
if ([NSKeyedArchiver archiveRootObject:glossay toFile:@"glossay.archiver"] == NO) {   
   NSLog(@"write file fail!!");   
}   
//取  
glossay = [NSKeyedUnarchiver unarchiveObjectWithFile:@"glossay.archiver"];  
NSLog(@"%@",[glossay valueForKey:@"key2"]);
对于自定义的Class,需要实现NSCoding协议,然后用上述方法二归档:

代码

//TestProperty.h   
  #import <Cocoa/Cocoa.h>   
@interface TestProperty : NSObject <NSCopying,NSCoding>{   
  NSString *name;   
  NSString *password;   
   NSMutableString *interest;   
  NSInteger myInt;   
}  
  12 @property (retain,nonatomic) NSString *name,*password;   
@property (retain,nonatomic) NSMutableString *interest;   
@property NSInteger myInt;   
-(void) rename:(NSString *)newname;   
@end   
====================   
//TestProperty.m   
  23 #import "TestProperty.h"   
  25  26 @implementation TestProperty   
  28 @synthesize name,password,interest;   
@synthesize myInt;   
-(void) rename:(NSString *)newname{   
   // 这里可以直接写成   
   // self.name = newname;   
  //   
    if (name != newname) {   
     [name autorelease];   
     name = newname;   
     [name retain];   
   }   
}   
-(void) dealloc{   
   self.name = nil;   
self.password = nil;   
  self.interest = nil;   
  [super dealloc];   
}   
- (id)copyWithZone:(NSZone *)zone{   
   TestProperty *newObj = [[[self class] allocWithZone:zone] init];   
   newObj.name = name;   
   newObj.password = password;   
    newObj.myInt = myInt;   
   //深复制   
   NSMutableString *tmpStr = [interest mutableCopy];   
     newObj.interest = tmpStr;   
  [tmpStr release];   
  //浅复制   
   //newObj.interest = interest;   
   return newObj;   
}   
- (void)encodeWithCoder:(NSCoder *)aCoder{   
   //如果是子类,应该加上:   
   //[super encodeWithCoder:aCoder];   
  //注意这里如何处理对象的(其实是实现了NSCoding的类)!   
    [aCoder encodeObject:name forKey: @"TestPropertyName"];   
      [aCoder encodeObject:password forKey:@"TestPropertyPassword"];   
       [aCoder encodeObject:interest forKey:@"TestPropertyInterest"];   
      //注意这里如何处理基本类型!   
     [aCoder encodeInt:myInt forKey:@"TestPropertyMyInt"];   
   }  
- (id)initWithCoder:(NSCoder *)aDecoder{   
   //如果是子类,应该加上:   
  //self = [super initWithCoder:aDecoder];   
   //解码对象   
    name = [[aDecoder decodeObjectForKey:@"TestPropertyName"] retain];   
     password = [[aDecoder decodeObjectForKey:@"TestPropertyPassword"] retain];   
    interest = [[aDecoder decodeObjectForKey:@"TestPropertyInterest"] retain];   
   //解码基本类型   
   myInt = [aDecoder decodeIntForKey:@"TestPropertyMyInt"];   
     return self;   
}   
  @end   
===============   
  //测试  
//存   
   TestProperty *test = [[TestProperty alloc] init];   
     test.name = @"pxl";  
     test.password = @"pwd...";  
    test.interest = [NSMutableString stringWithString:@"interest..."];  
     test.myInt = 123;  
       if([NSKeyedArchiver archiveRootObject:test toFile:@"testproerty.archive"] == NO){  
        NSLog(@"write to file fail!!");  
       }  
      //取  
    TestProperty *test = [NSKeyedUnarchiver unarchiveObjectWithFile:@"testproerty.archive"];  
   NSLog(@"%@",test.name);
使用NSData创建定义档案。

以上面已实现NSCoding协议的TestProperty类为例,代码

//存   
    TestProperty *test = [[TestProperty alloc] init];   
test.name = @"pxl";   
test.password = @"pwd...";   
  test.interest = [NSMutableString stringWithString:@"interest..."];   
  test.myInt = 123;   
NSMutableData *dataArea = [NSMutableData data];   
  NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:dataArea];  
  [archiver encodeObject:test forKey:@"testObj"];  
  //这里还可以加其它的对象13   //......  
[archiver finishEncoding];  
  if ([dataArea writeToFile:@"test.archiver" atomically:YES] == NO) {  
    NSLog(@"write to file fail...");  
  }  
[archiver release];  
[test release];  
============  
    //取  
   NSData *dataArea = [NSData dataWithContentsOfFile:@"test.archiver"];  
if(!dataArea){  
    NSLog(@"Can't read back archive file");  
    return (1);  
  }  
  NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:dataArea];   
TestProperty *test = [unarchiver decodeObjectForKey:@"testObj"];  
  [unarchiver finishDecoding];  
  NSLog(@"%@",test.name);  
  [unarchiver release];
利用归档实现对象深复制:

代码

//先删除TestProperty类中实现的NSCopying协议代码。   
TestProperty *test = [[TestProperty alloc] init];   
test.name = @"pxl";  
est.password = @"pwd...";   
test.interest = [NSMutableString stringWithString:@"interest..."];   
test.myInt = 123;   
//对test进行深复制10    NSData *data =  [NSKeyedArchiver archivedDataWithRootObject:test];11   
                   TestProperty *test2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];  
[test2.interest appendString:@"film"];  
NSLog(@"%@",test.interest);15   NSLog(@"%@",test2.interest);  
//输出  
2010-12-30 16:11:47.391 HelloWorld[4599:a0f] interest...  
2010-12-30 16:11:47.393 HelloWorld[4599:a0f] interest...film
小结:详解Objective-C归档问题解决的内容介绍完了,希望通过本文的学习能对你有所帮助!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2