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

Why is NSArray of NSNumber(s) failing to decode?

我有一个符合 NSSecureCoding 的自定义 class。我正在尝试对其数据进行编码,将其写入文件并对其进行解码。 class 包含一个 int 数组,我在编码之前将其转换为填充了 NSNumber 元素的 NSArray。当我解码数组时,decodeObjectForKey returns 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 是两者共享的类型。

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

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

这不安全。 NSSecureCoding 的全部要点是你告诉解码器你期望返回什么类型,这就是 -decodeObjectOfClass:forKey: 所做的。