1

NSDateの1つのキーの下にオブジェクトを保存しましたNSDictionary。次にNSDate、同じ日付値を持つ別のものを取得し、それを使用してからオブジェクトを取得しましたNSDictionary。驚いたことに、それは戻ってきnilました。しかし、私のデバッグセッション中に明らかになったことが、私の心をさらに驚かせました。

(lldb)po when
(NSDate *)$ 34 = 0x0f8be100 2012-05-11 21:08:37 +0000
(lldb)po [newTaskDict objectForKey:when]
(id)$ 36 = 0x00000000
(lldb)po [newTaskDict allKeys]
(id )$ 37 = 0x0f8c1650 <__ NSArrayI 0xf8c1650>(
2012-05-11 21:08:37 +0000

(lldb)po [[newTaskDict allKeys] lastObject]
(id)$ 38 = 0x0f8b5ff0 2012-05-11 21:08:37 + 0000
(lldb)p(int)[[[newTaskDict allKeys] lastObject] isEqual:when]
(int)$ 39 = 0
(lldb)po [[[newTaskDict allKeys] lastObject] class]
(id)$ 40 = 0x3f4496b0 __NSDate
(lldb) po [クラスの場合]
(id)$ 41 = 0x3f4496b0 __NSDate
(lldb)p(int)[[[newTaskDict allKeys] lastObject] isEqualToDate:when]
(int)$ 42 = 0
(lldb)p(int)[[[newTaskDict allKeys] lastObject] hash]
(int)$ 43 = 358463317
(lldb )p(int)[ハッシュ時]
(int)$ 44 = 358463317

ご覧のとおり、値が($ 38) で、ハッシュが($ 43)であるnewTaskDict、オリジナルによってキー設定されたエントリが1つだけあります。NSDate
0x0f8b5ff0 2012-05-11 21:08:37 +0000

35846331

NSDateエントリを取得するために使用したもう1つは($ 34):
0x0f8be100 2012-05-11 21:08:37 +0000
であり、そのハッシュは($ 44):です。
358463317

これらの2つNSDateは、メモリアドレスを除いて、まったく同じではありませんか?isEqual:($ 39)とisEqualToDate:($ 42)はどうやって彼らにNOを返すことができますか?

解決済み:
この奇妙な不平等は、によって引き起こされたことが判明しましたsub-second differences。受け入れられた答えの下にある私の2番目のコメントを読む必要があります。それは本当に興味深いものであり、知らない場合はいつかあなたを噛む可能性があるからです。

4

2 に答える 2

6

isEqualToDate:NSDateまた、ミリ秒も確認します。これは、人間にわかりやすい文字列のみをフォーマットするdescriptionメソッドであるため、オブジェクトをログに記録してもわかりませんが、日付オブジェクトの背後にはさらに多くの情報があります。

2つの日付は少し異なるように見えます。これは、同じ実行ループで作成された場合でも発生する可能性があります。1つを作成し、2つの参照で1つのオブジェクトのみを使用してから、2番目のテストでNSDate別々に作成された2つのオブジェクトをチェックします。次々と、それらは等しくてはいけません。

Appleのドキュメントを引用するには:

このメソッドは、日付間の1秒未満の差異を検出します。より細かい粒度で日付を比較する場合は、timeIntervalSinceDate:を使用して2つの日付を比較します。

https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/nsdate_Class/Reference/Reference.html

于 2012-05-12T03:03:40.027 に答える
1

isEqual to dateは、マイクロ秒まで比較されます。精度を下げる必要がある場合は、timeIntervalSinceDate:を使用して、日付が互いにマイクロ秒、秒、時間、日などの範囲内にあるかどうかをテストします。

isEqualは、メモリアドレス自体を使用して、同じオブジェクトかどうかを判断することがよくあります。これは、アドレスが異なる場合、それらは別々のオブジェクトであるためです。

于 2012-05-12T03:00:21.460 に答える