NSSet-用于检查NSValue是否相等的成员

| 我有一个
NSSet
,其中包含成千上万个
NSValue
对象(包装
CGPoints
)。我想非常迅速地找到
NSSet
中是否存在给定的
CGPoint
值。在我看来,
NSSet
member:
方法可能在这里起作用,除了它使用using7ѭ检查是否相等。
NSValue
对象使用
isEqualToValue:
,因此执行代码时:
[mySet member:valueToCheck];
实际上会导致Xcode崩溃。 1)有什么方法可以使用自定义的相等性检查来对
NSValue
对象起作用? 2)这是否是最好的方法(例如,
member:
首先够快)吗?场景是我有一个“ 0”,其中包含许多表示屏幕上像素的点(iPad)。稍后,我需要以每秒数千个点的速度轰炸该集合,以查看它们是否存在于集合中。我的方法似乎很粗糙,无法实现这一目标。我考虑过要创建一个像巨大的二维位数组之类的东西,每个索引代表屏幕上的一个像素。一旦知道要测试的点,我就可以直接跳到数组中的那个点并检查1或0 ...这听起来好还是坏? 谢谢     
已邀请:
你能把它变成一个简单的可复制的情况吗?例如,我刚刚尝试过:
NSValue *v = [NSValue valueWithCGPoint:CGPointMake(1, 1)];
NSSet *s = [NSSet setWithObject:v];
NSLog(@\"%@\", [s member:[NSValue valueWithCGPoint:CGPointMake(1, 1)]]);
但这很好。 编辑
-isEqual:
不是问题:
NSValue *v1 = [NSValue valueWithPoint:NSMakePoint(1, 1)];
NSValue *v2 = [NSValue valueWithPoint:NSMakePoint(1, 1)];
NSLog(@\"%d\", [v1 isEqual:v2]); //logs \"1\"
-hash
不是问题:
NSLog(@\"%d\", ([v1 hash] == [v2 hash])); //logs \"1\"
它们是不同的对象:
NSLog(@\"%d\", (v1 != v2)); //logs \"1\"
问题出在您的代码中。尝试清洁和重建。     
要回答不。 2: 我不知道NSSet是如何在内部实现的,但是考虑到您知道要存储点(使用X和Y),我认为通过实现自己的分区算法会更好。如果您说您有成千上万的观点,我个人会选择我自己的实现而不是NSSet。 为每个像素存储巨大的二维阵列可能是最快的方法,但是它将在内存消耗方面使您丧命。您需要快速但又轻巧的东西。 有很多算法,您可以通过在Wikipedia或google上搜索“空间分区算法”来找到它们。它还取决于您的编程技能,以及您愿意花多少时间在此上。 例如,一种非常简单的方法是实现四叉树,在该四叉树中,您将屏幕(或区域)分成4个相等的部分开始。然后,在需要的地方,将特定的单元格也分成4部分。然后执行此操作,直到每个单元格包含的点数足够少,以便可以对所有这些点进行蛮力测试。 您可以在Wiki上找到非常好的描述:http://en.wikipedia.org/wiki/Quadtree 希望这可以帮助,     
[mySet member:valueToCheck]
不应坠毁。当我在这里尝试时,NSValue的ѭ7可以很好地工作,实际上,当给另一个NSValue进行比较时,它可能会调用ѭ9。 ѭ23真的是NSValue还是CGPoint? 无法覆盖NSSet的默认哈希和比较方法。但是NSSet是免费的,以
CFSetRef
桥接,您可以在此处轻松地指定自定义哈希和比较方法:
CFSetCallBacks callbacks = kCFTypeSetCallBacks;
callbacks.equal = customEqualFunction;
callbacks.hash = customHashFunction;
NSMutableSet *set = (NSMutableSet *)CFSetCreateMutable(NULL, 0, &callbacks);
这些函数的约束可能与NSObject的
hash
isEqual:
方法相同,任何相等的哈希必须相同。此处和此处介绍了用于
customEqualFunction
customHashFunction
的C型原型。     
一种解决方案是子集
NSSet
和覆盖
member:
做您自己的比较。您自己的比较可以简单地叫ѭ9。看一下“ 0”文档中的子类注释。 另一种方法是在实现“ 7”的“ 1”中添加类别。在这种情况下,我宁愿使用子类化,因为它是一个更受约束的解决方案。     
ѭ15不仅有问题,而且-hash方法也可能有问题。如果要使用NSSet,则可能应该创建一个包装CGPoint的自定义类。
-isEqual:
然后是平凡的,
-hash
可以通过组合两个坐标的位然后将它们视为NSUInteger的某种方法来实现。 您还将想要实现
NSCopying
协议,如果您的积分是不变的,那么这也是微不足道的(只需保留并返回in40ѭ中的self)。     

要回复问题请先登录注册