2013-04-10 33 views
3

我有一個人的類,覆蓋方法的isEqual:iOS版 - NSArray的indexOfObject不叫的isEqual定製

#import "People.h" 

@implementation People 
@synthesize name = _name; 


-(BOOL)isEqual:(id)object { 
    NSLog(@"A.isEqual called"); 

    if ([object isKindOfClass:[NSString class]]) { 
     NSString *name = object; 
     return [self.name isEqualToString:name]; 
    } 
    return [super isEqual:object]; 
} 

@end 

當我找到一個數組的人,它不調用方法的isEqual:

People* p1 = [People new]; 
     p1.name = @"A"; 

     People* p2 = [People new]; 
     p2.name = @"B"; 

     NSArray* peopleArray = [NSArray arrayWithObjects:p1, p2, nil]; 

     NSLog(@"find A %ld", [peopleArray indexOfObject:@"A"]); 

     NSLog(@"isEqual A -> %@", [p1 isEqual:@"A"] ? @"Yes" : @"No"); 

這裏是輸出:

2013-04-10 18:15:47.988 runone[6273:303] find A 9223372036854775807 
2013-04-10 18:15:47.988 runone[6273:303] A.isEqual called 
2013-04-10 18:15:47.989 runone[6273:303] isEqual A -> Yes 

你知道爲什麼?

+0

你有在.h中聲明嗎? – 2013-04-10 11:45:11

+0

不,我沒有,Anoop – thanhbinh84 2013-04-11 02:54:52

+0

在那裏聲明,你的方法會被調用。 – 2013-04-11 03:36:22

回答

7

即使蘋果的文檔saysisEqual:發送到陣列中的每個對象,但它周圍的其他方法 - 發送isEqual:您正在搜索的對象。

由於它假設[a isEqual:b] == [b isEqual:a],它應該不會在大多數情況下有所不同,但在你的情況下,它使。

下面是一個例子:

People* p1 = [People new]; 
p1.name = @"A"; 

People* p2 = [People new]; 
p2.name = @"B"; 

People* p3 = [People new]; 
p3.name = @"C"; 

NSArray* peopleArray = [NSArray arrayWithObjects:p1, p2, p3, nil]; 

NSLog(@"find A %ld", (unsigned long)[peopleArray indexOfObject:p3]); 

和人們方法的isEqual:

-(BOOL)isEqual:(id)object 
{ 
    NSLog(@"A.isEqual called %@", [self name]); 
    ... 
} 

輸出:

A.isEqual called C 
A.isEqual called C 
find A 2 
+3

這是正確的。數組的實現將調用NSString的isEqual:方法,傳入每個Person。這將始終返回NO,因爲它們是不同的類型。因此人和NSString相等是不對稱的。如果你定義了isEqual :,你還需要定義-hash,即使NSArray當前不調用它。 – 2013-04-10 12:36:26

+0

如果Apple的文檔是正確的,那將會很棒!我在這一段時間追逐了我的尾巴。 – LavaSlider 2015-05-09 15:17:13

4

如果a == b,然後b == a

或者,在Objective-C而言,如果[a isEqual:b],然後[b isEqual:a]必須也是如此

您的-isEqual:違反了該規則。

NSArray如何使用isEqual:方法完全是一個實現細節超出了isEqual:將用於遏制測試

+0

我不同意這一點的話,那不是一個遏制問題。蘋果的文檔明確指出了行爲的相反情況。 – Jon 2013-08-30 14:38:45

1

由於kovpas的回答,我改變的isEqual方法與新的想法,以適應:

#import "People.h" 

@implementation People 
@synthesize name = _name, age = _age; 


-(BOOL)isEqual:(id)object { 
    NSLog(@"A.isEqual called"); 

    if ([object isKindOfClass:self.class]) { 
     People *p = object; 
     return [self.name isEqualToString:p.name]; 
    } 
    return [super isEqual:object]; 
} 

@end 

然後添加所需的字符串比較爲人們

 People* p1 = [People new]; 
     p1.name = @"A"; 

     People* p2 = [People new]; 
     p2.name = @"B"; 

     NSArray* peopleArray = [NSArray arrayWithObjects:p1, p2, nil]; 

     People* p3 = [People new]; 
     p3.name = @"A"; 

     NSLog(@"find A %ld", [peopleArray indexOfObject:p3]); 

它會像一個魅力:)

2013-04-11 10:28:55.659 runone[1029:303] A.isEqual called 
2013-04-11 10:28:55.659 runone[1029:303] find A 0