2011-11-08 66 views
6


我想要一個簡單的NSSet,它加載了一些NSNumbers,然後找出這些數字是否已經添加到集合中。當我這樣做:NSSet的NSNumbers - 成員方法始終爲零

NSMutableSet *set = [[NSMutableSet alloc] init]; 
NSNumber *num1 = [NSNumber numberWithInt:5]; 
NSNumber *num2 = [NSNumber numberWithInt:5]; 
[set addObject:num1]; 
if([set member:num2]){ 
    // something... 
} 

問題是,成員總是返回零(如果爲false),即使這些數字是相同的。 isEqual方法返回true。所以

if([num1 isEqual:num2]){ 
    // correct 
} 

作品...
在文檔,我讀了成員方法的isEqual使用,所以我不知道是什麼問題... 感謝您的任何意見。

+0

如果你的代碼被正確粘貼 - 你沒有添加對象num2到你的集合 – Maggie

+0

你確定..你的代碼對我來說工作得很好! – Devarshi

+0

@Maggie是的我確定,關鍵是我想檢查數字5是否已經在集合中,但我必須使用nsnumber,因爲它們是對象,所以我想檢查值爲5的nsnumber對象是否已經在集(num1與值爲5是,所以它應該返回true) – haluzak

回答

2

問題是,您正在檢查如果num1num2是相同的對象。而他們不是。它們具有相同的值,但它們是具有相同值的兩個不同對象。

所以你檢查member是他們在內存中是否有相同的地址。

編輯:您應該使用compare來檢查數字的值是否相同!

+0

「他們是否有相同的地址在記憶中「是不真實的;根據'member:'docs:「如果集合包含一個對象等於對象(由isEqual決定:)那麼該對象(通常這將是對象),否則爲零。」 – Wevah

+0

你們都可以是對的......我似乎記得NSNumber有一個鬼鬼祟祟的優化,它有前幾個整數的靜態表示。在這種情況下,內存地址_and_ isEqual將起作用。 – jrturton

+0

當然,但不應該以任何方式返回錯誤。 – Wevah

4

有必要比較NSNumbers的值,而不是對象。

可以使用objectsPassingTest:

實施例:

NSMutableSet *set = [[NSMutableSet alloc] init]; 
NSNumber *num1 = [NSNumber numberWithInt:5]; 
NSNumber *num2 = [NSNumber numberWithInt:5]; 
NSNumber *num3 = [NSNumber numberWithInt:3]; 
[set addObject:num1]; 

NSSet *filteredSet; 
filteredSet = [set objectsPassingTest:^(id obj,BOOL *stop){ 
    return [obj isEqualToNumber:num2]; 
}]; 
NSLog(@"Contains num2: %@", (filteredSet.count == 1) ? @"YES" : @"NO"); 

filteredSet = [set objectsPassingTest:^(id obj,BOOL *stop){ 
    return [obj isEqualToNumber:num3]; 
}]; 
NSLog(@"Contains num3: %@", (filteredSet.count == 1) ? @"YES" : @"NO"); 

的NSLog輸出:

Contains num2: YES 
Contains num3: NO 

或者,如果使用謂詞期望:

filteredSet = [set filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"SELF == %@", num2]]; 
NSLog(@"Contains num2: %@", (filteredSet.count == 1) ? @"YES" : @"NO"); 

filteredSet = [set filteredSetUsingPredicate:[NSPredicate predicateWithFormat:@"SELF == %@", num3]]; 
NSLog(@"Contains num3: %@", (filteredSet.count == 1) ? @"YES" : @"NO"); 
2

鱈魚e可當我運行它

NSMutableSet *set = [[NSMutableSet alloc] init]; 
NSNumber *num1 = [NSNumber numberWithInt:5]; 
NSNumber *num2 = [NSNumber numberWithInt:5]; 
[set addObject:num1]; 
if([set member:num2]){ 
    NSLog(@"Hello, world"); 
    } 
+0

這是不完全有效的,因爲如果我將* num1的值更改爲6後,我將它添加到集合中,然後詢問[set member num1]和[set member num2]是否都返回true。 –

+0

@RyanHeitner,你如何改變一個NSNumber對象?他們是不變的! – ragnarius

+0

NSNumber * num1 = [NSNumber numberWithInt:5]; [set addObject:num1]; num1 = [NSNumber numberWithInt:6]; –

4

當您使用的NSArray你需要的值進行比較,而不是對象本身,因爲你好字被寫入日誌。您可以使用NSMutableIndexSet來代替使用NSArray。這使您可以將這些值與少幾個步驟進行比較。

//during init, add some numbers 
NSMutableIndexSet *tSet = [[NSMutableIndexSet alloc] init]; 
NSUInteger exampleValue = 7; 
[tSet addIndex:exampleValue]; 
exampleValue = 42; 
[tSet addIndex:exampleValue]; 

//...later on 
//look to see if numbers are there 
if ([tSet containsIndex:7]){ 
    NSLog(@"7 exists!"); 
} 
if ([tSet containsIndex:8]){ 
    NSLog(@"8 exists!"); 
} 

產量: 7存在!