2

NSOrderedSet类参考概述说:

当元素的顺序很重要并且测试对象是否包含在集合中的性能是一个考虑因素时,您可以使用有序集合作为数组的替代方案——测试数组的成员资格比测试集合的成员资格慢。

哪些方法被认为是“成员资格测试”?只是containsObject:?或者,也会indexOfObjectPassingTest:更快?

我问是因为如果我只有对象的 ID(例如来自服务器)并且想要检查有序集是否包含具有该 ID 的对象,我会使用indexOfObjectPassingTest:. 但是,由于它测试集合中的每个对象,该方法似乎与数组一样慢。另一方面,containsObject:似乎它会更快,因为它利用了NSObject方法hash& isEqual:。我可以使用我拥有的 ID 创建一个探测对象,然后使用containsObject:. 但是,如果有序集中已经包含具有该 ID 的对象,我将丢弃探测对象并更新已在有序集中的对象的属性。首先必须创建一个探测对象似乎是额外的工作。在这种情况下,是否值得在数组上使用有序集?

另外,我会按对象的日期而不是 ID 对对象进行排序。

正如St3fan 所建议的那样,我会使用NSMutableDictionary带有对象 ID 的对象映射到对象,但我也想在.UITableView

4

2 回答 2

0

您可以覆盖-isEqual:-hash在您的班级中。如果这样做,它将与NSOrderedSet' 快速查找一起使用。它可以很简单:

- (BOOL)isEqual:(id)otherObject
{
    return self.myID == otherObject.myID;
}

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

这是一个完整的例子:

#import <XCTest/XCTest.h>

@interface MyClass : NSObject
@property (nonatomic) NSInteger myID;
@property (nonatomic, strong) NSDate *date;
@end

@implementation MyClass

- (BOOL)isEqual:(MyClass*)otherObject
{
    return self.myID == otherObject.myID;
}

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

@end

@interface MyTests : XCTestCase

@end

@implementation MyTests

- (void)testExample
{
    MyClass *obj1 = [[MyClass alloc] init];
    obj1.myID = 1;
    obj1.date = [NSDate dateWithTimeIntervalSince1970:20000];

    MyClass *obj2 = [[MyClass alloc] init];
    obj2.myID = 2;
    obj2.date = [NSDate dateWithTimeIntervalSince1970:10000];

    MyClass *obj3 = [[MyClass alloc] init];
    obj3.myID = 1;
    obj3.date = [NSDate dateWithTimeIntervalSince1970:30000];

    MyClass *obj4 = [[MyClass alloc] init];
    obj4.myID = 3;
    obj4.date = [NSDate dateWithTimeIntervalSince1970:30000];

    NSOrderedSet *set = [[NSOrderedSet alloc] initWithArray:@[obj1, obj2]];
    XCTAssertEqualObjects(((MyClass *)[set firstObject]).date, obj1.date);
    XCTAssertEqualObjects(((MyClass *)[set lastObject]).date, obj2.date);
    XCTAssertTrue([set containsObject:obj1]);
    XCTAssertTrue([set containsObject:obj3]);
    XCTAssertFalse([set containsObject:obj4]);
}

@end
于 2013-10-20T15:33:47.433 回答
0

最好的测试方法是编写一些小的基准。我不知道你正在处理多少个对象,但如果它少于几百个,那么你可能不会注意到 之间有太大区别containsObject:indexOfObjectPassingText:甚至只是手动迭代所有对象。

听起来NSMutableDictionary实际上更适合您的用例。为什么不将对象存储在由对象 ID 索引的字典中?然后,您可以通过 ID 快速找到它们,如果需要,您还可以轻松地遍历它们。

于 2013-10-20T15:34:28.463 回答