2016-12-07 4 views
3

私はObjective-Cで知っています==isEqual:とはまったく異なります。しかし、次のコードが32ビットと64ビットのiOSデバイスで一貫して異なる結果を生み出す理由が不思議です。32ビットと64ビットのiOSデバイスで==の動作が異なるのはなぜですか?

NSIndexPath* a = [NSIndexPath indexPathForItem:0 inSection:0]; 
NSIndexPath* b = [NSIndexPath indexPathForItem:0 inSection:0]; 
NSLog(@"%@", a == b ? @"YES" : @"NO"); 
NSLog(@"%@", [a isEqual:b] ? @"YES" : @"NO"); 

32ビットデバイスでは、 iPhone 5、==は常に失敗します(予想されます)。

2016-12-07 09:55:18.019 NSIndexPathTestObjc[18667:1958831] NO 
2016-12-07 09:55:18.020 NSIndexPathTestObjc[18667:1958831] YES 

たとえば、64ビットデバイスでは、次のようになります。 iPhone 6s、==が成功しました(予期しない)。私はObjective-Cの==に知っ

2016-12-07 09:56:05.503 NSIndexPathTestObjc[18780:1960472] YES 
2016-12-07 09:56:05.505 NSIndexPathTestObjc[18780:1960472] YES 
+0

'a == b'を実行しているときは、オブジェクトではなくポインタを比較していません。あなたは2つのオブジェクトを作成しているので、一致してはいけません。 なぜ64でこれが真実であるか私にも面取り。 – rckoenes

+3

@rckoenes Typo - あなたのコメントに余分な "not"があります。 – rmaddy

答えて

4

はのisEqualとは非常に異なっている:

はい - あなたは2つのオブジェクトを比較するために、後者を使用する必要があります。 ==は、比較しているポインタが同じかどうかだけを示します。

しかし、次のコードが32ビットと64ビットのiOSデバイスで一貫して異なる結果をもたらす理由が不思議です。

これはおそらく、それが64ビットシステムで生成され、キャッシュされたオブジェクトにあなたが同じ項目でメソッドを呼び出す二度目を返すインデックスパスをキャッシュしますが、doesnのかもしれない-indexPathForItem:inSection:の実装の詳細、可能です32ビットシステムでは動作しません。この動作に依存しないでください:-isEqual:をオブジェクトの比較に使用してください。

+3

あなたは 'indexPathForItem:inSection:'がそのキャッシングをしていることを知っていますか、それとも単なる推測ですか?私は、==動作するということは、 'NSIndexPath'がキャッシングではなく64ビットデバイス上でタグ付きポインタを使用していることを意味している可能性が非常に高いと思います。 – dan

+0

@dan NSIndexPathがどのように実装されているかわからないので、ちょっと推測してください。私はそれをより明確にするために* might *を追加しました。あなたの推測はおそらくより良いものですが、ここで最も重要なのは、それが重要ではないということです。これは約束された行動でも、それに依存するべき行動でもありません。私は '=='がinjudiciouslyで使用され、定数ではない文字列が初めて使用されたときに比較が突然機能しなくなる、文字列に関する同様の問題を見てきました。 – Caleb

+0

@Calebいくつかの情報源によるとObjective-Cの文字列は最適化として "string interning"を使用するので、文字列の値は複数のポインタに渡って共有されるので、 '=='のように見えます。 'NSIndexPath'でも同じことが起こっているとは思っていましたが、確かに見つけ出すことはできませんでした。 – bejonbee

関連する問題