首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSOrderedSet诉NSArray indexOfObjectPassingTest:

NSOrderedSet诉NSArray indexOfObjectPassingTest:
EN

Stack Overflow用户
提问于 2013-10-20 15:22:50
回答 2查看 1.8K关注 0票数 2

NSOrderedSet类引用概述指出:

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

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

我之所以这样问是因为,如果我只有对象的ID (例如来自服务器),并且希望检查有序的集合是否包含一个带有该ID的对象,我将使用indexOfObjectPassingTest:。但是,这个方法,因为它测试集合中的每个对象,看起来就像数组一样慢。另一方面,containsObject:似乎更快,因为它利用了NSObject方法hash & isEqual:。我可以用我的ID创建一个探测对象,然后使用containsObject:。但是,如果有序集已经包含了一个带有该ID的对象,那么我将放弃探测对象,并更新已在有序集中的对象的属性。首先创建一个探测对象似乎是额外的工作。在这种情况下,是否值得在数组上使用有序集?

另外,我将根据对象的日期,而不是它们的ID对其进行排序。

我会使用带有对象in映射到对象的NSMutableDictionary,如St3fan建议,但我也希望在UITableView中显示对象。

EN

回答 2

Stack Overflow用户

发布于 2013-10-20 15:33:47

您可以在类中重写-isEqual:-hash。如果您这样做,它将与NSOrderedSet的快速查找一起工作。

代码语言:javascript
复制
- (BOOL)isEqual:(id)otherObject
{
    return self.myID == otherObject.myID;
}

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

下面是一个完整的例子:

代码语言:javascript
复制
#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
票数 0
EN

Stack Overflow用户

发布于 2013-10-20 15:34:28

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19479141

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档