NSKeyedArchiver unarchiveObjectWithData 返回具有 nil 值的对象

Posted

技术标签:

【中文标题】NSKeyedArchiver unarchiveObjectWithData 返回具有 nil 值的对象【英文标题】:NSKeyedArchiver unarchiveObjectWithData returning object with nil values 【发布时间】:2018-08-07 13:08:58 【问题描述】:

UserBean .h 文件

@property (assign, readwrite) NSString *user;
@property (assign, readwrite) NSString *timestamp;
@property (assign, readwrite) NSString *password;
@property (assign, readwrite) NSString *source_id;
@property (assign, readwrite) NSString *fullname;
@property (assign, readwrite) NSString *email;
@property (assign, readwrite) NSString *reset_code;

- (void)encodeWithCoder:(NSCoder *)encoder;
- (id)initWithCoder:(NSCoder *)decoder;

UserBean .m 文件

- (void)encodeWithCoder:(NSCoder *)encoder 
    //Encode properties, other class variables, etc
    [encoder encodeObject:self.email forKey:@"email"];
    [encoder encodeObject:self.user forKey:@"username"];
    [encoder encodeObject:self.fullname forKey:@"fullname"];
    [encoder encodeObject:self.password forKey:@"password"];
    [encoder encodeObject:self.source_id forKey:@"id"];
    [encoder encodeObject:self.timestamp forKey:@"timestamp"];

- (id)initWithCoder:(NSCoder *)decoder 
    if((self = [super init])) 
        //decode properties, other class vars
        self.email = [decoder decodeObjectForKey:@"email"];
        self.user = [decoder decodeObjectForKey:@"username"];
        self.fullname = [decoder decodeObjectForKey:@"fullname"];
        self.password = [decoder decodeObjectForKey:@"password"];
        self.source_id = [decoder decodeObjectForKey:@"id"];
        self.timestamp = [decoder decodeObjectForKey:@"timestamp"];
    
    return self;

这里我保存并取回 userbean 类对象

- (UserBean *)getUser                       
    NSError *error;
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSData *encodedObject = [defaults objectForKey:@"user"];
    if (@available(ios 9.0, *)) 
        UserBean *userBean = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:encodedObject error:&error];
        return userBean;
     else 
        UserBean *userBean = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];
        return userBean;
    

- (void)saveUser:(UserBean *)userBean       
    NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:userBean];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:encodedObject forKey:@"user"];
    [defaults synchronize];

从这里我设置对象属性并保存

- (void)saveUser:(StandardPacket *)packet               
    NSDictionary *dataDict = [packet.data objectAtIndex:0];
    UserBean *userBean = [[UserBean alloc] init];

    userBean.user = [NSString stringWithFormat:@"%@",[dataDict objectForKey:@"username"]];
    userBean.email = [NSString stringWithFormat:@"%@",[dataDict objectForKey:@"email"]];
    userBean.fullname = [NSString stringWithFormat:@"%@",[dataDict objectForKey:@"fullname"]];
    userBean.password = [NSString stringWithFormat:@"%@",[dataDict objectForKey:@"password"]];
    userBean.source_id = [NSString stringWithFormat:@"%@",[dataDict objectForKey:@"id"]];

    userBean.timestamp = @"AA";
    userBean.reset_code = @"AA";

    [[SharedPrefences defaults] saveUser:userBean];

但是当我从 SharedPreferences 中检索对象时,我得到的对象是 nil 值和其他垃圾

线程 1:EXC_BAD_ACCESS(代码=1,地址=0xa17e4c52)

检索后来自 userbean 对象的值

用户 UserBean * 0x17e604e0 _user NSString * 0x17ea9fe0

_timestamp NSString * 0x17ea7a50

_password NSString * 0x17e605c0

_source_id NSString * 0x17e679d0

_fullname NSString * 0x17ea9e50

_email NSString * 0x17e9a880

_reset_code NSString * nil 0x00000000

【问题讨论】:

【参考方案1】:

您缺少编码 in encodeWithCoder:(NSCoder *)encoder 函数。

[encoder encodeObject:self.reset_code forKey:@"reset_code"];

另外,添加 initWithCoder:(NSCoder *)decoder 函数。

 self.reset_code = [decoder decodeObjectForKey:@"reset_code"];

希望对你有帮助。

【讨论】:

谢谢,但我发现问题出在@property (assign, readwrite) (property type) 它正在从属性中释放值 欢迎您。我认为这不是唯一的问题,因为从错误日志中可以看到,_reset_code NSString * nil 0x00000000 是 nil。它没有被编码,因此在解码时它为零。不管怎样,你解决了这个问题真是太好了。

以上是关于NSKeyedArchiver unarchiveObjectWithData 返回具有 nil 值的对象的主要内容,如果未能解决你的问题,请参考以下文章

ansibel的unarchive模块

自定义类 Unarchive 在 Cocoa Swift 中为零

ansible 之 archive&unarchive

ansible-unarchive模块

Unarchive UIImage 对象在 iOS 8 上使用 NSKeyedUnarchiver 返回 CGSizeZero 图像

NSKeyedArchiver 保存啥格式?