web-dev-qa-db-ja.com

NSArraycontainsObjectメソッド

Xcodeコーディングに関して簡単な質問がありますが、なぜ物事が思ったように機能しないのかわかりません。オブジェクト(カスタムオブジェクト)の配列があります。これが配列内にあるかどうかを確認したいだけです。次のコードを使用しました。

NSArray *collection = [[NSArray alloc] initWithObjects:A, B, C, nil]; //A, B, C are custom "Item" objects
Item *tempItem = [[Item alloc] initWithLength:1 width:2 height:3];  //3 instance variables in "Item" objects
if([collection containsObject:tempItem]) {
    NSLog(@"collection contains this item");
}

上記のチェックで良い結果が得られると思いますが、そうではありません。さらに、作成したオブジェクトが同じかどうかを確認しました。

NSLog(@"L:%i W:%i H:%i", itemToCheck.length, itemToCheck.width, itemToCheck.height);
for (int i = 0, i < [collection count], i++) {
    Item *itemInArray = [collection objectAtIndex:i];
    NSLog(@"collection contains L:%i W:%i H:%i", itemInArray.length, itemInArray.width, itemInArrayheight);
}

コンソールでは、これが私が得たものです:

L:1 W:2 H:3
collection contains L:0 W:0 H:0
collection contains L:1 W:2 H:3
collection contains L:6 W:8 H:2

明らかに、tempItemcollection配列内にありますが、containsObject:を使用してチェックしても何も表示されません。誰かが私に間違っている部分を教えてもらえますか?どうもありがとう!

17
Anthony

[NSArray containsObject:] のドキュメントによると:

このメソッドは、isEqual:メッセージを各レシーバーのオブジェクトに送信する(およびパラメーターとしてanObjectを各isEqual:メッセージに渡す)ことにより、anObjectがレシーバーに存在するかどうかを判別します。

問題は、オブジェクトの値ではなく、オブジェクトへの参照を比較していることです。この特定の例を機能させるには、[collection containsObject:]に含まれる変数のインスタンス(例:AB、またはC)を送信する必要があります。または、Itemクラスの [NSObject isEqual:] メソッドをオーバーライドする必要があります。

isEqualメソッドは次のようになります。

- (BOOL)isEqual:(id)other {
    if (other == self)
      return YES;
    if (!other || ![other isKindOfClass:[self class]])
      return NO;
    if (self.length != other.length || self.width != other.width || self.height != other.height)
      return NO;
    return YES;
}

より良い実装のために、あなたはこれを見たいかもしれません 質問

41
Senseful