我从我的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”的只读变量@synthesized。在我的应用程序的32位版本上,这是在调用setValue:(id)value forUndefinedKey:(NSString *)key
之前立即设置的。我在该方法中引用此值,并且在我的应用程序的64位版本上,当断点命中此方法时,类型尚未设置。
显然,这不是最好的行动方案。我只是想知道是否有其他人看到这个,或者我是在咆哮错误的树。我在两个版本之间区分了文件,它们是相同的。我在iOS 8.1模拟器上运行它们,API为两者返回相同的东西......我很难过。基本上在旧版本中定义的键在未定义之前设置,而在新版本上它似乎与之相反。
答案 0 :(得分:2)
NSDictionary
个对象是无序集合,因此代码永远不应该假设字典将枚举其自己的键的顺序。事实证明,32位和64位运行时之间存在实现差异,这些差异会影响最终存储散列值的位置。
由于API合约明确地不保证订单,这不应该导致问题,但它可以(并且在这种情况下显然确实)具有引起以前代码的副作用在为64位架构编译时,它会工作。
解决您目前遇到的问题而不会显着改变实现的快速方法是自己枚举字典的密钥,这样您就可以提供按顺序排列的密钥数组:
- (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];
}
}