NSOrderedSet Class Reference概述说:
当元素的顺序很重要时,您可以使用有序集作为数组的替代,并且在测试集合中是否包含对象时的性能是一个考虑因素 - 对数组成员资格的测试比测试成员的成员资格要慢集。
哪种方法被视为“会员资格测试”?只是containsObject:
?或者,indexOfObjectPassingTest:
也会更快吗?
我问,因为如果我只有对象的ID(例如来自服务器)并且想要检查有序集是否包含具有该ID的对象,我将使用indexOfObjectPassingTest:
。但是,该方法,因为它测试集合中的每个对象,似乎它与数组一样慢。另一方面,containsObject:
似乎更快,因为它利用了NSObject
方法hash
& isEqual:
。我可以使用我拥有的ID创建一个探测对象,然后使用containsObject:
。但是,如果有序集已经包含具有该ID的对象,我将丢弃探测对象并更新已在有序集中的对象的属性。首先必须创建探测对象似乎是额外的工作。在这种情况下,是否值得在数组上使用有序集?
另外,我会按日期排序对象,而不是ID。
我使用NSMutableDictionary
将对象ID映射到对象,St3fan suggested,但我也希望在UITableView
中显示对象。
答案 0 :(得分: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
答案 1 :(得分:0)
测试这个的最好方法是编写一些小基准。我不知道你正在处理多少个对象,但如果它少于几百个,那么你可能不会注意到containsObject:
,indexOfObjectPassingText:
之间的差别,甚至只是手动迭代所有对象
听起来NSMutableDictionary
实际上更适合您的用例。为什么不将对象存储在由对象ID索引的字典中?然后你可以通过ID快速找到它们,如果需要你也可以轻松地迭代它们。