Ios 如何将NSKeyedUnarchiveObjectWithData更新为NSKeyedUnarchiveObjectOfClass:[fromData:错误:

Ios 如何将NSKeyedUnarchiveObjectWithData更新为NSKeyedUnarchiveObjectOfClass:[fromData:错误:,ios,objective-c,nscoder,nsarchiving,Ios,Objective C,Nscoder,Nsarchiving,我的应用程序当前使用此不推荐的功能: id unarchivedObject=[NSKeyedUnarchiver unarchiveObjectWithData:codedData]; if([unarchivedObject isKindOfClass:[NSDictionary class]]){ // currently returns TRUE when reading existing user data. } 要更新,我已转换为: id unarchivedObject

我的应用程序当前使用此不推荐的功能:

id unarchivedObject=[NSKeyedUnarchiver unarchiveObjectWithData:codedData];
if([unarchivedObject isKindOfClass:[NSDictionary class]]){
    // currently returns TRUE when reading existing user data.
} 
要更新,我已转换为:

id unarchivedObject=[NSKeyedUnarchiver unarchivedObjectOfClass:[NSDictionary class] fromData:codedData error:nil];
if([unarchivedObject isKindOfClass:[NSDictionary class]]){
    // currently returns FALSE when reading existing user data.
}
数据最初是这样编码的:

-(void)encodeWithCoder:(NSCoder*)encoder{
    [encoder encodeObject:text forKey:@"text"];
}
-(instancetype)initWithCoder:(NSCoder*)decoder{
    if(self=[super init]){
        text=[decoder decodeObjectForKey:@"text"];
}
使用较新的代码时,是什么导致IF语句返回FALSE


请注意,我主要关心的是在弃用归档功能之前读取存储的现有数据。简单地更改为较新的功能并不能解决此问题。

有趣的问题!我一直支持iOS 10.0,所以在看到此问题之前,我从未遇到过此类问题。我修补了一个小时,成功了我发现了这个问题

是什么原因导致IF语句使用较新的 密码

这是因为您的
unarchivedObject
对象是nil

如果在新方法中使用参数
error
,将看到如下错误:

-(void)encodeWithCoder:(NSCoder*)encoder{
    [encoder encodeObject:text forKey:@"text"];
}
-(instancetype)initWithCoder:(NSCoder*)decoder{
    if(self=[super init]){
        text=[decoder decodeObjectForKey:@"text"];
}
错误域=NSCOCAERRORDOMAIN Code=4864“此解码器将仅 解码采用NSSecureCodeding的类。类“QTPerson”不 采用它。“UserInfo={NSDebugDescription=此解码器将仅进行解码 采用NSSecureCodeding的类。类“QTPerson”不采用它

但是我们如何为这个
unarchivedObject
而不是nil获得正确的值呢?这需要几个步骤

首先,使您的模型/类符合

例如: QTPerson.h

#import <Foundation/Foundation.h>

@class QTPerson;

NS_ASSUME_NONNULL_BEGIN

#pragma mark - Object interfaces

@interface QTPerson : NSObject <NSCoding, NSSecureCoding>
@property (nonatomic, copy) NSString *text;
@end

NS_ASSUME_NONNULL_END

然后在存档对象时,您需要将
YES
传递给参数
requireingsecurecoding
,如下所示:

QTPerson *person = [[QTPerson alloc] init];
person.text = @"Glenn";

NSData *codedData1 = [NSKeyedArchiver archivedDataWithRootObject:person requiringSecureCoding:YES error:nil];
[[NSUserDefaults standardUserDefaults] setValue:codedData1 forKey:@"boom"];
NSData *codedData = [[NSUserDefaults standardUserDefaults] dataForKey:@"boom"];

NSError *er;
id unarchivedObject=[NSKeyedUnarchiver unarchivedObjectOfClass:[QTPerson class] fromData:codedData error:&er];

if([unarchivedObject isKindOfClass:[QTPerson class]]){
    NSLog(@"TRUE!");
} else {
    NSLog(@"FALSE!");
}

最后,当不归档时,只需正确地执行所做的操作,如下所示:

QTPerson *person = [[QTPerson alloc] init];
person.text = @"Glenn";

NSData *codedData1 = [NSKeyedArchiver archivedDataWithRootObject:person requiringSecureCoding:YES error:nil];
[[NSUserDefaults standardUserDefaults] setValue:codedData1 forKey:@"boom"];
NSData *codedData = [[NSUserDefaults standardUserDefaults] dataForKey:@"boom"];

NSError *er;
id unarchivedObject=[NSKeyedUnarchiver unarchivedObjectOfClass:[QTPerson class] fromData:codedData error:&er];

if([unarchivedObject isKindOfClass:[QTPerson class]]){
    NSLog(@"TRUE!");
} else {
    NSLog(@"FALSE!");
}

瞧!你会得到一个非空的对象
unarchivedObject
,因此你要寻找的是真的/是的值!

谢谢你的代码/研究,但是在实现后,我在读取现有数据时仍然会得到一个空的未归档对象-这才是真正的问题。我可以删除此应用程序更新的现有数据并重新开始,无论是否存在ng应用程序的用户将丢失他们的数据,我不希望这样做。@wayneh你找到解决方案了吗?@Davidvanduggeren没有,我还没有解决这个问题。目前我已从应用程序商店中取出我的应用程序。