NSSecureCoding returns nil 对于正确保存的对象
NSSecureCoding returns nil for properly saved object
我在 macOS 10.15 (bigSUr),XCode 12,objective-c 不是 ios。
我有基于文档的应用程序。它有一个简单的对象“SHGlobalAppData”(NSObject),其中包含自定义 class“SHSetupDataModel”(NSObject)的 属性 对象。
加载时,initWithCoder returns nil 为一个保存值。为什么?
这是实现:
我使用 NSSecureCoding,因此 SHSetupDataModel 和 SHGlobalAppData 都包含了适当的 class 方法
+ (BOOL)supportsSecureCoding { return YES;}
使用安全编码在 NSDocument 中完成保存
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
NSKeyedArchiver* archiver=[[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
[archiver encodeObject:self.appData forKey:@"appData"]; // SHSetupDataModel is a property of appData object
//[...]
}
如何保存
说到保存,这是SHGlobalAppData的代码
- (void)encodeWithCoder:(NSCoder *)coder {
// Other properties here
if (_setupData){
// Tests
NSLog(@"%@",[_setupData className]); // returns "SHSetupDataModel"
BOOL test = [_setupData isKindOfClass:[SHSetupDataModel class]]; // returns TRUE
[coder encodeObject:_setupData forKey:@"setupData"];
}
}
以上节省顺利进行。测试没问题。
加载是如何完成的
现在加载保存的文件时,会调用以下 NSDocument 方法:
- (BOOL)readFromURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError *__autoreleasing _Nullable *)outError {
NSData* data = [[NSData alloc] initWithContentsOfURL:url];
NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:outError];
[unarchiver setRequiresSecureCoding:YES];
// Load appData
SHGlobalAppData* appData = [unarchiver decodeObjectOfClass:[SHGlobalAppData class] forKey:@"appData"];
[unarchiver finishDecoding];
// [...]
}
这从 SHGlobalAppData 调用了 initWithCoder 方法 - 我得到了一个零结果
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
if ([coder containsValueForKey:@"setupData"]){
_setupData = [coder decodeObjectOfClass:[SHSetupDataModel class] forKey:@"setupData"]; // <---- This is nil. Why?
}
// [...]
}
}
任何人都可以帮助我为什么这返回零?或者引导我进行更有效的调试?
数据模型本身包含一个未正确解码的 NSDictionary。解决方案是分析 outError,然后通过 initWithCoder 方法逐步工作。
最后我不得不在 decodeObjectWithClasses:ofKey:
中传递多个 类
我在 macOS 10.15 (bigSUr),XCode 12,objective-c 不是 ios。
我有基于文档的应用程序。它有一个简单的对象“SHGlobalAppData”(NSObject),其中包含自定义 class“SHSetupDataModel”(NSObject)的 属性 对象。
加载时,initWithCoder returns nil 为一个保存值。为什么?
这是实现:
我使用 NSSecureCoding,因此 SHSetupDataModel 和 SHGlobalAppData 都包含了适当的 class 方法
+ (BOOL)supportsSecureCoding { return YES;}
使用安全编码在 NSDocument 中完成保存
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError {
NSKeyedArchiver* archiver=[[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
[archiver encodeObject:self.appData forKey:@"appData"]; // SHSetupDataModel is a property of appData object
//[...]
}
如何保存
说到保存,这是SHGlobalAppData的代码
- (void)encodeWithCoder:(NSCoder *)coder {
// Other properties here
if (_setupData){
// Tests
NSLog(@"%@",[_setupData className]); // returns "SHSetupDataModel"
BOOL test = [_setupData isKindOfClass:[SHSetupDataModel class]]; // returns TRUE
[coder encodeObject:_setupData forKey:@"setupData"];
}
}
以上节省顺利进行。测试没问题。
加载是如何完成的
现在加载保存的文件时,会调用以下 NSDocument 方法:
- (BOOL)readFromURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError *__autoreleasing _Nullable *)outError {
NSData* data = [[NSData alloc] initWithContentsOfURL:url];
NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:outError];
[unarchiver setRequiresSecureCoding:YES];
// Load appData
SHGlobalAppData* appData = [unarchiver decodeObjectOfClass:[SHGlobalAppData class] forKey:@"appData"];
[unarchiver finishDecoding];
// [...]
}
这从 SHGlobalAppData 调用了 initWithCoder 方法 - 我得到了一个零结果
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
if ([coder containsValueForKey:@"setupData"]){
_setupData = [coder decodeObjectOfClass:[SHSetupDataModel class] forKey:@"setupData"]; // <---- This is nil. Why?
}
// [...]
}
}
任何人都可以帮助我为什么这返回零?或者引导我进行更有效的调试?
数据模型本身包含一个未正确解码的 NSDictionary。解决方案是分析 outError,然后通过 initWithCoder 方法逐步工作。 最后我不得不在 decodeObjectWithClasses:ofKey:
中传递多个 类