2013-10-20 45 views
2

NSOrderedSet Class Reference概述說:NSOrderedSet VS的NSArray indexOfObjectPassingTest:

您可以使用有序集來替代陣列時元素的順序是在測試中非常重要和性能對象是否包含在一組是考慮 - 測試數組的成員資格比測試組的成員資格要慢。

哪些方法被視爲「測試成員資格」?只需containsObject:?或者,indexOfObjectPassingTest:也會更快?

我在問,因爲如果我只有對象的ID(例如來自服務器),並且想要檢查有序集是否包含具有該ID的對象,則使用indexOfObjectPassingTest:。但是,該方法因爲它測試集合中的每個對象,似乎它會像數組一樣慢。另一方面,containsObject:似乎會更快,因爲它利用了NSObject方法hash & isEqual:。我可以用我擁有的ID創建探測對象,然後使用containsObject:。但是,如果有序集合已經包含具有該ID的對象,我將放棄探測對象並更新已有序集合中的對象的屬性。看起來需要額外的工作才能首先創建探測對象。在那種情況下,它甚至值得在數組上使用有序集合嗎?

此外,我會排序對象的日期,而不是他們的ID。

我會使用一個NSMutableDictionary與映射到對象的對象ID,如St3fan suggested,但我也想顯示UITableView中的對象。

回答

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 
+0

是的,但它加快' - [NSOrderedSet indexOfObjectPassingTest:]'? – ma11hew28

+0

不,因爲必須在'NSOrderedSet'中的每個對象上調用謂詞塊。 –

0

測試最好的方法是通過編寫一些小的基準。我不知道你處理了多少個對象,但是如果它少於幾百個,那麼你可能不會注意到containsObject:,indexOfObjectPassingText:之間的很多差異,甚至只是手動迭代所有對象。

聽起來像一個NSMutableDictionary實際上更適合您的用例。爲什麼不將對象存儲在由對象ID編入索引的字典中?然後,您可以通過ID很快找到它們,並且如果需要,您還可以輕鬆地對它們進行迭代。

+0

但是,我想要在'UITableView'中顯示對象。 – ma11hew28