在NSDictionary中使用SKNode对象作为键? (比较问题)

时间:2016-05-14 18:38:17

标签: objective-c sprite-kit

目标-C

考虑以下代码:

SKNode *n1 = [SKNode new];
SKNode *n2 = [SKNode new];

NSMutableDictionary *d = [NSMutableDictionary new];

[d setObject:@"A" forKey:n1];
[d setObject:@"B" forKey:n2];


if ([d objectForKey:n1]) {
    NSLog(@"true");
}

我在NSDictionary中使用SKNode作为键。我需要测试给定的SKNode是否作为Key存在。测试的常用方法似乎不起作用,因为上面的结果不会返回(或打印)" true"。以下代码也不会出现:

if ([d allKeys] containsObject:n1]) {
    NSLog(@"true");
}

如果我制作钥匙串;即@" key1",@" key2"," true"打印出来。

有可能以这种方式进行测试吗?

2 个答案:

答案 0 :(得分:3)

(在我看来,我作为评论写的内容实际上就是问题的答案。)

NSDictionary复制其密钥(使用NSCopying协议中的-copy)。 SKNode符合NSCopying,但复制节点会返回一个不等于旧节点的新节点:

SKNode *a = [SKNode new];
SKNode *b = [a copy];

[a isEqual:b];  // NO
let a = SKNode()
let b = a.copy() as! SKNode

a == b  // false

因此,在字典中使用SKNodes作为键是不安全的。至于变通方法:您可以使用节点name作为密钥(如果您的节点名称是唯一的)。您也可以使用NSMapTable,它不会复制其密钥。

答案 1 :(得分:1)

您的代码应该有效。所以这里出了点问题,可能是实现了hashcode和isNqual:SKNode的方法。

记录两个密钥的哈希码,检查isEqual:返回,记录字典和所有密钥,并检查是否有任何意外。

PS。它变成jtbandes回答是正好正确的。当然,根据我的建议和记录所有内容,你会发现allKeys中的键不是预期的,有机会找出答案。

因此,如果你有一个具有普通哈希码和isEqual的类,只需将指针作为哈希码并比较isEqual的指针,那么要么你有一个类,其中copy创建一个新对象和一个字典赢了不起作用,或者你有一个类,副本只返回原始对象,它工作正常。