15

重複の可能性:
Obj-c のオブジェクトの比較

オブジェクトの等価性をチェックするこれら 2 つの方法の違いは何ですか。

UIButton *btn1 = [[UIButton alloc] init];
UIButton *btn2 = [[UIButton alloc] init];

違いは何ですか:

if (btn1 == btn2) {
  // Run some code
}

if ([btn1 isEqual:btn2]) {
  // Run some code
}
4

3 に答える 3

19

最初の方法はポインターを比較し、2 番目の方法はオブジェクトを比較します。

つまり、最初の方法は、ポインターが同じ値を持っているかどうかを比較します。この場合、そうではない可能性が高く、2 番目のケースではオブジェクトが比較されます。それらは同じ方法で初期化されるため、等しい可能性があります。(注:UIButtonの実装ではisEqual:、結果は常に false になるようです。)

ほとんどの場合、使用==はあなたが望むものではありません。ただし、何が適切かは目的によって異なります。

于 2012-12-26T06:10:04.093 に答える
15

Prateekの答えとThomasの編集された答えは正しいです。しかし、この種のケースに対処する際によくある落とし穴/混乱を追加したいだけです..

このケースを考えてみましょう

 NSString *str1  = [[NSString alloc] initWithString:@"hello"];
 NSString *str2  = [[NSString alloc] initWithString:@"hello"];

理想的str1str2は、2 つの異なる文字列オブジェクトである必要があり、str1 と str2 は異なるアドレスを指している必要があります。ただし、以下のコードを実行すると印刷されますstr1 == str2

if(str1 == str2){
    NSLog(@"str1 == str2");
}

以下のコードプリントstr1 isEqual str2

if([str1 isEqual:str2]){
    NSLog(@"str1 isEqual str2");
}

その理由は、渡された 2 つの同一の文字列リテラルがinitWithStringstart に同じアドレスを持つため、同じオブジェクトでもあるからです (これを参照してください)。これは、定数データの最適化です。これは、iOS (および私が感じる他の多くの実装) の機能です。

ただし、これは他の種類のオブジェクト/クラスでは機能しません。2 を作成するUIButtonと、それらは完全に異なるオブジェクトになり、両方btn1btn2(質問を参照) は異なるアドレスを指します。

于 2012-12-26T06:43:39.103 に答える
5

コメントで言及された違い

if (btn1 == btn2) //This compared your pointers
{
  // Run some code
}

if ([btn1 isEqual:btn2]) //Compares UIButton object
{
  // Run some code
}
于 2012-12-26T06:12:01.893 に答える