gpt4 book ai didi

objective-c - 将 NSArray 转换为 NSSet,自定义类实例传输不一致

转载 作者:太空狗 更新时间:2023-10-30 03:36:02 33 4
gpt4 key购买 nike

遇到一个有趣的小问题。我正在编写一种方法来将数组过滤为唯一对象:

- (NSArray*)distinctObjectsByAddress {
NSSet* uniqueSet = [NSSet setWithArray:self];
NSArray* retArray = [uniqueSet allObjects];

return retArray;
}

并编写了一个单元测试来检查:

- (void)testDistinctObjectsByAddress5 {
Person* adam1 = [[Person alloc] initWithFirstName:@"adam" lastName:@"adam" andParent:nil];
Person* adam2 = [[Person alloc] initWithFirstName:@"adam" lastName:@"adam" andParent:nil];

testPersonArray = [NSArray arrayWithObjects:adam1,adam2, nil];

NSArray* checkArray = [testPersonArray distinctObjectsByAddress];

STAssertEquals([checkArray count], [testPersonArray count], @"Array %@ counts should match %@ %@",checkArray,adam1,adam2);
}

很简单。有趣的是,大约有 80-90% 的时间测试通过,但有时会失败,因为 distinctObjectsByAddress 方法只返回一个对象。我已经能够将其追溯到 [NSSet setWithArray:self] 调用,但我也能够验证这两个人对象是两个不同的对象(至少它们具有不同的地址) .我假设 setWithArray: 只是在进行基本地址比较,但我不明白为什么它有时会像它应该的那样生成两个对象,有时只生成一个对象。

我刚刚尝试更改 adam2,以便名字和姓氏与 adam1 不完全相同。这似乎修复了错误。当对象在逻辑上相同时,这是否指向某种编译器优化?

最佳答案

I'm assuming that setWithArray is just doing a basic address compare

这是不正确的。 NSSet 在添加到它的对象上使用 -isEqual:-hash 方法。这取决于它们在 Person 或其父类(super class)中的实现方式。

如果 [person1 isEqual:person2] 那么您会期望该集合包含一个对象。如果不是,则该集合应包含两个对象。

我的猜测是 Person 没有遵循 the rules在其 -isEqual:-hash 方法中。最有可能的是,这两个对象是相等的,但它们的哈希值并不像它们应该的那样相等。 (除了 10-20% 的幸运时间。)

Does this point to some sort of compiler optimization when the objects are logically the same?

不,没有将两个对象合并为一个的编译器优化。

关于objective-c - 将 NSArray 转换为 NSSet,自定义类实例传输不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9355203/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com