在调用NSSet的setByAddingX方法时,哪些对象赢得平局?

我提出这个问题,因为与isEquals相比较的对象:不一定相同。一些(许多)对象仅比较某些属性以确定相等性。 这使得以下NSSet方法的确切行为很重要:
setByAddingObject:
setByAddingObjectsFromArray:
setByAddingObjectsFromSet:
文档没有说明当接收器和参数包含等效对象时会发生什么。生成的NSSet是否包含来自接收器的对象,或来自“其他”参数的对象? 请注意,在NSMutableSet中,它指定了其添加方法的行为 - 如果集合中已存在“相等”对象,则不会添加对象。     
已邀请:
NSMutableSet的
addObject:
方法的文档用于涵盖类似的案例:   如果集合中已存在
anObject
,则此方法对集合或
anObject
无效。 但是,正如您从链接中看到的那样,当前版本甚至没有这么说。甚至那个声明实际上只包括尝试添加相同的对象;它没有专门解决添加不同但相同的对象的问题。 依赖于观察到但未记录的行为是危险的,不仅因为它可以在OS版本之间进行更改,还因为它可以在同一个过程中进行更改。那是因为NSSet是一个类集群,这意味着可能有多个实现。你得到哪一个取决于你如何创建集合;没有办法确保选择或甚至存在特定的实施。* 那是因为它无关紧要。每个集群子类都表现出与集群接口和文档中定义的行为相同的行为。 (如果它没有,那就是一个bug,你应该报告它。)鉴于所有的子类都有效地做同样的事情,你应该得到哪一个实例并不重要。 同样的原则适用于您的对象。他们是平等的!出于这个原因,集合中的哪一个无关紧要。如果它确实重要,那么它们就不是真正平等的,你需要使对象对平等的定义更加严格。 (别忘了更新
isEqual:
hash
。) 根据您使用的设置,您可能希望更进一步,并确保不存在两个相同的对象。为此,将集合的所有权,维护和使用移动到成员对象的类中,并使其始终返回匹配的对象,而不是在可能和适当的情况下创建新对象。 *即使你可以选择其中一个实现,也不能保证它会有你永远观察到的行为 - 它可能,而墨菲说可能会在另一个操作系统版本中有所不同。     
我用以下代码测试了这个。 SomeClass的定义使得propertyA是hash和isEquals中唯一考虑的属性:
SomeClass *objectA = [[[SomeClass alloc] init] autorelease];
objectA.propertyA = @"test";
objectA.propertyB = @"objectA";

SomeClass *objectB = [[[SomeClass alloc] init] autorelease];
objectB.propertyA = @"test";
objectB.propertyB = @"objectB";

NSSet *setA = [NSSet setWithObject:objectA];
NSSet *setB = [NSSet setWithObject:objectB];
NSSet *setC = [setA setByAddingObjectsFromSet:setB];

NSLog(@"Set An%@", [setA description]);
NSLog(@"Set Bn%@", [setB description]);
NSLog(@"Set Cn%@", [setC description]);
运行此代码时的输出是:
2011-03-03 16:35:15.041 temp[50311:207] Set A
{(
    {SomeClass propertyA:test propertyB:objectA}
)}
2011-03-03 16:35:15.041 temp[50311:207] Set B
{(
    {SomeClass propertyA:test propertyB:objectB}
)}
2011-03-03 16:35:15.042 temp[50311:207] Set C
{(
    {SomeClass propertyA:test propertyB:objectA}
)}
这表明,在参数包含等效对象的情况下,新创建的NSSet将包含来自RECEIVER的对象。 编辑 - 我将此标记为答案,因为它直接回答了手头的问题。但是,我会指出彼得的答案以及他所表达的担忧。这种行为没有记录,因此,虽然这些核心类在这方面极不可能发生变化,但值得指出风险。如果您编写代码假设此行为,则可能会在将来的版本中中断。买者自负。     

要回复问题请先登录注册