gpt4 book ai didi

ios - distinctUnionOfObjects 不工作

转载 作者:行者123 更新时间:2023-11-28 19:01:43 24 4
gpt4 key购买 nike

我创建了简单的 XCTest 来测试 distinctUnionOfObjects。除了 isKindOfClass (Last XCTAssertTrue) 之外,所有测试用例都通过了。知道为什么在执行 distinctUnionOfObjects 时它会更改类。

- (void)testUsersPredicate
{
NSArray *usersBeforePredicate = [[self userData] users];
XCTAssertEqual([usersBeforePredicate count] , 34u, @"We need 34");
XCTAssertTrue([[usersBeforePredicate lastObject] isKindOfClass:[ICEUsersModelObject class]], @"Object is not ICEUsersModelObject class");

NSString *distinctUsersKeyPath = [NSString stringWithFormat:@"@distinctUnionOfObjects.%@", @"userName"];
NSArray* usersAfterPredicate = [usersBeforePredicate valueForKeyPath:distinctUsersKeyPath];

XCTAssertEqual([usersAfterPredicate count] , 30u, @"We need 30");
XCTAssertTrue([[usersAfterPredicate lastObject] isKindOfClass:[ICEUsersModelObject class]], @"Object is not ICEUsersModelObject class");
}

最佳答案

由于 distinctUnionOfObjects 上的正确键路径是 userName-valueForKeyPath: 调用将返回一个 NSArray 不同的用户名(不是用户对象)。

来自 Apple 的 KVC Programming Guide :

The @distinctUnionOfObjects operator returns an array containing the distinct objects in the property specified by the key path to the right of the operator.

更改最后一个测试用例以检查 [NSString class],它应该会通过。

备选方案

使用相等:

如果 userName 属性应该用作唯一标识符,您可以通过覆盖 -isEqual:-hash 来强制执行它用户对象来反射(reflect)这一点:

- (BOOL)isEqual:(id)object {
return ([object isKindOfClass:self.class] && [object.userName isEqual:self.userName]);
}

- (NSUInteger)hash {
return self.userName.hash;
}

这可以使您的整体模型设计受益并打开许多其他选项,例如获得不同用户注册集合的选项。一行中的 userName - NSSet 用于此时非常快:

NSArray *uniqueUsers = [[NSSet setWithArray:users] allObjects];
  • 注意:我将NSString的哈希函数重新用于用户哈希,这有一个微妙的陷阱; -[NSString hash] 只保证最多 96 个字符的字符串的唯一性!这不在文档中,我花了将近一天的时间来追踪生产代码。 (参见 Apple 的 CFString.c 实现 - 搜索 __CFStrHashCharacters)

使用 NSPredicate:

比方说,这是一个使用谓词的“创造性”解决方案。但是,需要某种迭代,否则谓词条件必须是其自身结果的函数:

NSMutableArray *__uniqueUsers = [NSMutableArray array];
[[users valueForKeyPath:@"@distinctUnionOfObjects.userName"] enumerateObjectsUsingBlock:^(id name, NSUInteger idx, BOOL *stop) {
NSArray *uniqueUser = [users filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id user, NSDictionary *bindings) {
return [user.userName isEqual:name];
}]];
if (uniqueUser.count > 0)
[__uniqueUsers addObject:uniqueUser.lastObject];
}];
NSArray *uniqueUsers = [NSArray arrayWithArray:__uniqueUsers];

它获取一组唯一的用户名,对其进行迭代,为每个名称选择一个用户并将其添加到输出数组。

关于ios - distinctUnionOfObjects 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24397062/

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