简体   繁体   English

Obj-C setValuesForKeysWithDictionary 64位与32位

[英]Obj-C setValuesForKeysWithDictionary 64-bit vs 32-bit

I am pulling a JSON object from my API and creating it using the following code (in hindsight not the way to go): 我正在从我的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];
}

One of the keys is "type". 键之一是“类型”。 I have a read-only variable @synthesized called "type". 我有一个名为“ type”的只读变量@synthesized。 On the 32-bit version of my app, this is set right away before setValue:(id)value forUndefinedKey:(NSString *)key is called. 在我的应用程序的32位版本上,此设置在setValue:(id)value forUndefinedKey:(NSString *)key之前立即设置。 I reference this value in that method, and on the 64-bit version of my app, when the breakpoint hits this method, type is not set yet. 我在该方法中引用此值,并且在我的应用程序的64位版本上,当断点命中该方法时,尚未设置类型。

Clearly this isn't the best course of action. 显然,这不是最佳的做法。 I am just wondering if anyone else as seen this or if I'm barking up the wrong tree. 我只是想知道是否有人看到过这种情况,或者我在吠错树。 I diffed the files between the two versions and they are identical. 我在两个版本之间比较了文件,它们是相同的。 I am running them both on iOS 8.1 Simulator, the API is returning the same thing for both...I'm stumped. 我都在iOS 8.1 Simulator上运行它们,API两者都返回相同的东西...我很困惑。 Basically on the old version defined keys are set before undefined, and on the new version it seems the opposite of that. 基本上,在旧版本中,已定义键是在未定义之前设置的,而在新版本中,这似乎是相反的。

NSDictionary objects are unordered collections, so code should never make assumptions about the order in which a dictionary will enumerate its own keys. NSDictionary对象是无序集合,因此代码绝不应该假设字典枚举其自身键的顺序。 It turns out that there are implementation differences between the 32- and 64-bit runtimes that affect where hashed values end up being stored. 事实证明,在32位和64位运行时之间存在实现差异,这些差异会影响哈希值最终存储在何处。

Since the API contract explicitly doesn't guarantee order, that shouldn't cause problems, but it can (and in this case apparently does ) have the side-effect of causing code that formerly 'worked' to break when compiled for the 64-bit architecture. 由于API合约明确地不保证顺序,因此不会引起问题,但是它(在这种情况下显然) 确实具有副作用,导致在为64-位架构。

A quick way to fix the problem you're currently having without significantly changing the implementation would be to enumerate the dictionary's keys yourself, which would allow you to provide an array of keys ordered however you wish: 解决当前存在的问题而又不显着更改实现的一种快速方法是自己枚举字典的键,这将使您能够提供所需顺序的键数组:

- (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];
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM