如何归档和取消归档NSObject?

时间:2015-08-21 16:29:06

标签: ios objective-c game-center nsobject nskeyedarchiver

我正在尝试存档我在游戏中心回合制游戏中通过匹配数据发送的NSObject。

以下是我存档对象的代码

turnDataObject MyData = [[turnDataObject alloc] init];

data = [NSKeyedArchiver archivedDataWithRootObject:MyData];

这是我取消归档我的对象的代码

readMyData = [NSKeyedUnarchiver unarchiveObjectWithData:data] ;

然而,当我运行此代码时,我收到错误

 thread 1 exc bad access code

我认为这可能与我归档数据时发送地址有关。当我取消归档时,如何发送可读的内容?

编辑1:我取消归档后,我在下一行收到错误。它说我试图访问的地址是空的。我记得在某个地方读过我不能发送我的NSObject的地址,但我不知道如何将它转换成别的东西。

readMyData = [NSKeyedUnarchiver unarchiveObjectWithData:data] ;

NSLog(@"current game happens to be: %@", readMyData.currentGame);

编辑2:这是我的编码器初始化程序,用编码器编码

 - (instancetype)initWithCoder:(NSCoder *)decoder
 {
     self = [self init];
     if (self) {

         _currentGame = [decoder decodeObjectForKey:currentGameDataKey];

    }
    return self;
 } 

 - (void)encodeWithCoder:(NSCoder *)encoder
 {

    //scores data keys
    [encoder encodeObject:self.currentGame forKey:currentGameDataKey];

 }

编辑3:_currentGame在我的对象.h文件

 @property (assign, nonatomic) NSString *currentGame;

3 个答案:

答案 0 :(得分:0)

我建议创建NSKeyedArchiver和NSKeyedUnarchiver对象并使用它们而不是使用类型(它看起来像你正在做的那样。)

我通常使用Swift进行编程,但这里是一个示例代码:

theArchiver NSKeyedArchiver = [[theArchiver alloc] init];
data = [theArchiver archivedDataWithRootObject:MyData];

然后你会对NSKeyedUnarchiver做同样的事情。

答案 1 :(得分:0)

您的initWithCoder实施错误:

 self = [self init];

应该是:

 self = [super init];

答案 2 :(得分:-1)

您需要将NSCoding协议添加到MyData Class,这里是支持NSCoding的代码片段,以便为NSObjet添加Archiving支持。

MyData.h

@interface MyData : NSObject <NSCoding>
@property (nonatomic, strong) NSString *currentGame;
@end

MyData.m

//This method is optional, if you need constructor for current game 
- (instancetype)initWithCurrentGame:(NSDictionary *)currentGame {
    self = [super init];
    if (self) {
        self.currentGame = currentGame;
    }
    return self;
}


-(void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.currentGame forKey:@"currentGame"];
}

-(id)initWithCoder:(NSCoder *)decoder {
    self.currentGame = [decoder decodeObjectForKey:@"currentGame"];
    return self;
}