Objective c 为NSDictionary中的键使用SKNode对象?(比较问题)

Objective c 为NSDictionary中的键使用SKNode对象?(比较问题),objective-c,sprite-kit,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"); } 我正在使用SKNode作为NSDi

目标-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");
}
我正在使用SKNode作为NSDictionary中的键。我需要测试给定的SKNode是否作为密钥存在。常用的测试方法似乎不起作用,如上所述,结果不会返回或打印为真。以下代码也不适用:

if ([d allKeys] containsObject:n1]) {
    NSLog(@"true");
}
如果我把钥匙串起来;i、 e@key1,@key2,true已打印


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

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

记录两个键的哈希代码,检查isEqual:返回的内容,记录字典和所有键,并检查是否有任何意外情况

顺便说一句,现在看来杰班德斯的答案正是正确的。当然,按照我的建议,记录所有您可能会发现allKeys中的键不是预期的键的内容,并且很有可能找到答案


因此,如果您有一个包含普通hashcode和isEqual的类,只是将指针作为hashcode并比较isEqual的指针,那么要么您有一个类,其中copy创建了一个新对象,而字典无法工作,要么您有一个类,其中copy只返回原始对象,并且工作正常

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

记录两个键的哈希代码,检查isEqual:返回的内容,记录字典和所有键,并检查是否有任何意外情况

顺便说一句,现在看来杰班德斯的答案正是正确的。当然,按照我的建议,记录所有您可能会发现allKeys中的键不是预期的键的内容,并且很有可能找到答案


因此,如果您有一个包含普通hashcode和isEqual的类,只是将指针作为hashcode并比较isEqual的指针,那么要么您有一个类,其中copy创建了一个新对象,而字典无法工作,要么您有一个类,其中copy只返回原始对象,并且工作正常

我突然想到,我写的评论实际上是对这个问题的回答

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

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

[a isEqual:b];  // NO

因此,将SKNodes用作字典中的键是不安全的。至于解决方法:如果节点的名称是唯一的,则可以使用节点的名称作为键。您也可以使用NSMapTable,它不会复制它的键。

我突然想到,我写的评论实际上就是这个问题的答案

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

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

[a isEqual:b];  // NO

因此,将SKNodes用作字典中的键是不安全的。至于解决方法:如果节点的名称是唯一的,则可以使用节点的名称作为键。您也可以使用NSMapTable,它不会复制其键。

我只是在objective c中做了相同的实验,但由于没有对结果的解释而犹豫回答。通常情况下,[[object copy]isEqual:object]==YES,不是吗?这就是为什么符合NSCopying对于字典键来说就足够了。如果这是真的,那么它会有直观的意义,我认为在大多数情况下都是真的,但我甚至不认为它是NSCopying的非正式要求。似乎SKNode选择实现复制以允许您克隆节点,考虑到这一目标,新节点与旧节点不相等是有道理的。我刚刚发现了一篇好文章,讨论了使用NSDict与NSMapTable的区别/优势。是的,NSMapTable还有一系列其他功能,这些功能非常有用。但是,对于这样的情况,您只需要StrongToStrongObjectsMastable,除了键复制之外,您基本上可以获得与NSMutableDictionary相同的行为。我只是在objective c中做了相同的实验,但由于没有对结果的解释,所以不愿回答。通常情况下,[[object copy]isEqual:object]==YES,不是吗?这就是为什么符合NSCopying对于字典键来说就足够了。如果这是真的,那么它会有直观的意义,我认为在大多数情况下都是真的,但我甚至不认为它是NSCopying的非正式要求。似乎SKNode选择实现复制以允许您克隆节点,考虑到这一目标,新节点与旧节点不相等是有道理的。我刚刚发现了一篇好文章,讨论了使用NSDict与NSMapTable的区别/优势。是的,NSMapTable还有一系列其他功能,这些功能非常有用。但是,对于这种情况,您只需要strongToStrongObjectsMasptable,除了key-copying.copy创建新对象之外,基本上可以获得与NSMutableDictionary相同的行为 ct不取消将对象用作字典键的资格。在副本中执行alloc是典型的,并且新对象和原始对象产生冲突哈希并一起回答isEqual==true是典型和可取的。复制创建新对象并不取消将该对象用作字典键的资格。在副本中执行alloc是典型的,并且新对象和原始对象产生冲突哈希并一起回答isEqual==true是典型且可取的。