簡體   English   中英

如何將 NSKeyedUnarchiver unarchiveObjectWithData 更新為 NSKeyedUnarchiver unarchivedObjectOfClass:[fromData:error:

[英]How to update NSKeyedUnarchiver unarchiveObjectWithData to NSKeyedUnarchiver unarchivedObjectOfClass:[fromData:error:

我的應用程序目前使用這個已棄用的 function:

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 語句使用較新的代碼返回 FALSE?

這是因為你的unarchivedObject object 是nil

如果您在新方法中使用參數error ,您會看到如下錯誤:

錯誤域=NSCocoaErrorDomain Code=4864 "此解碼器將僅解碼采用 NSSecureCoding 的類。Class 'QTPerson' 不采用它。" UserInfo={NSDebugDescription=此解碼器只會解碼采用 NSSecureCoding 的類。 Class 'QTPerson' 不采用。

但是我們如何獲得這個unarchivedObject而不是 nil 的正確值呢? 這需要幾個步驟。

首先,讓你的模型/類符合<NSCoding, NSSecureCoding>

示例: 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

然后實現協議方法:

QTPperson.m

#import "QTPerson.h"

@implementation QTPerson

+ (BOOL)supportsSecureCoding {
    return YES;
}

- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:_text forKey:@"text"];
}

- (instancetype)initWithCoder:(NSCoder *)coder {
    self = [super init];
    if (self) {
        _text = [coder decodeObjectOfClass:[NSString class] forKey:@"text"];
    }
    return self;
}

@end

然后在歸檔 object 時,您requiringSecureCodingYES傳遞給參數 requiresSecureCoding ,如下所示:

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!");
}

瞧! 您將獲得非空 object unarchivedObject ,因此您正在尋找 TRUE/YES 值!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM