为什么 NSNumber(s) 的 NSArray 无法解码?

问题描述

我有一个符合 NSSecureCoding自定义类。我正在尝试对其数据进行编码,将其写入文件并对其进行解码。该类包含一个 int 数组,我在编码之前将其转换为一个 NSArray 填充的 NSNumber 元素。当我解码数组时,decodeObjectForKey 返回 nil。此外,当我将编码的数组写入文件时,plist 看起来不正确。例如,它的结构中的任何地方都没有“key_for_ns_array”键。

这是我的代码的简化版本:

@interface c_my_data_wrapper : NSObject <NSSecureCoding>
@property (assign,nonatomic) struct s_my_data my_data; // the array exists as an int[] in here
@end
@implementation c_my_data_wrapper

- (void)encodeWithCoder:(NSCoder *)encoder
{
    NSMutableArray *ns_array= [NSMutableArray array];
    int_array_to_ns_array(self.my_data.my_int_array,count,ns_array);

    [encoder encodeObject:ns_array forKey:@"key_for_ns_array"];
}

- (instancetype)initWithCoder:(NSCoder *)decoder
{
    self= [self init];
    
    if (self)
    {
        // this returns nil
        NSArray *ns_array= [decoder decodeObjectForKey:@"key_for_ns_array"];
    }

    return self;
}

@end
c_secure_storage_data_wrapper* g_my_data_wrapper= nil; // allocation not shown
void store_data(struct s_storage_data_secure *new_data)
{
    g_my_data_wrapper.my_data= *new_data;

    NSData *encoded_data=
        [NSKeyedArchiver archivedDataWithRootObject:g_my_data_wrapper
                              requiringSecureCoding:YES
                                              error:nil];

    // then I write the encoded data to a file
}
void load_data(void)
{
    NSData *decoded_data= [NSData dataWithContentsOfURL:my_url];

    g_my_data_wrapper=
        [NSKeyedUnarchiver unarchivedobjectOfClass:[c_my_data_wrapper class]
                                          fromData:decoded_data
                                             error:nil];
}
void int_array_to_ns_array(
    int *int_array,int count,NSMutableArray *out_ns_array)
{
    for (int index= 0; index < count; ++index)
    {
        [out_ns_array addobject:[NSNumber numberWithInt:int_array[index]]];
    }
}

如果您对整个 int 数组到 ns 数组的转换感到好奇……那是因为我更喜欢用 C++ 编写。我对objective-c不是很熟悉,所以我只在需要弥合我的游戏和iOS之间的差距时才写它。在这种情况下,s_my_data 是一种在两者之间共享的类型。

解决方法

一个问题,可能是问题,是您声称您的类符合 NSSecureCodeing,但您仍在调用 -decodeObjectForKey: 而不是 -decodeObjectOfClass:forKey: :

NSArray *ns_array= [decoder decodeObjectForKey:@"key_for_ns_array"];

这不安全。 NSSecureCoding 的全部意义在于您告诉解码器您希望返回什么类型,这就是 -decodeObjectOfClass:forKey: 所做的。