Obj-C setValuesForKeysWithDictionary 64 位与 32 位

Obj-C setValuesForKeysWithDictionary 64-bit vs 32-bit

我正在从我的 API 中提取一个 JSON 对象并使用以下代码创建它(事后看来不是正确的方法):

+ (YActivity *)instanceFromDictionary:(NSDictionary *)jsonDictionary
{
    YActivity * instance = [[YActivity alloc] init];
    [instance setAttributesFromDictionary:jsonDictionary];
    return instance;
}

- (void)setAttributesFromDictionary:(NSDictionary *)jsonDictionary
    {
        if (![jsonDictionary isKindOfClass:[NSDictionary class]]) {
            return;
        }

        [self setValuesForKeysWithDictionary:jsonDictionary];
}

其中一个键是"type"。我有一个名为 "type" 的只读变量 @synthesized。在我的应用程序的 32 位版本上,这是在调用 setValue:(id)value forUndefinedKey:(NSString *)key 之前立即设置的。我在那个方法中引用了这个值,在我的应用程序的 64 位版本上,当断点命中这个方法时,类型还没有设置。

显然这不是最好的做法。我只是想知道是否有其他人看到了这个,或者我是否在咆哮错误的树。我比较了两个版本之间的文件,它们是相同的。我是 运行 他们都在 iOS 8.1 模拟器上,API 为两者返回相同的东西......我很难过。基本上在旧版本上 defined 键设置在 undefined 之前,而在新版本上似乎与此相反。

NSDictionary 对象是无序集合,因此代码不应该假设字典枚举其自己的键的顺序。事实证明,32 位和 64 位运行时之间的实现差异会影响散列值最终存储的位置。

由于 API 合同明确不保证顺序,这不应该引起问题,但它可以(在这种情况下显然 确实 )在为 64 位架构编译时导致以前 'worked' 中断的代码的副作用。

在不显着改变实现的情况下解决您当前遇到的问题的一种快速方法是自己枚举字典的键,这将允许您提供一个按您希望的方式排序的键数组:

- (void)setAttributesFromDictionary:(NSDictionary *)dictionary
{
    // So instead of doing this...
    //
    // [self setValuesForKeysWithDictionary:dictionary];

    // You could do something along these lines:
    //
    NSMutableArray *keys = dictionary.allKeys.mutableCopy;

    // TODO: insert code to change the order of the keys array.
    // Then loop through the keys yourself...

    for (NSString *key in keys)
    {
        [self setValue:dictionary[key] forKey:key];
    }
}