質問: [[NSDate alloc] initWithString:@"2000-12-31 23:59:59 +0000"]; ``` とするとdate1の参照先が変わってもdate2はこの日付を保持し、nullになりません。なぜでしょうか。また扱うデータの型をNSString型にしても、同じように弱い参照のみで参照しているオブジェクトが解放されないようです。よろしくお願いします。
回答: ``` NSLog(@"%d", (int)CFGetRetainCount((__bridge CFTypeRef)date1)); ``` で参照カウンタを見れば分かりますが、`initWithString:`で生成した`NSDate`は`-1`(解放不要)が返却されます。 弱参照がゼロ化される条件は、ランタイムが管理しているオブジェクト毎の参照カウントが0になった場合なので、解放されないオブジェクトに対しては`__weak`は機能しません。 同じ`NSDate`でも挙動が違うのは、クラスクラスタにより生成されるクラスそのものが違うためです。 ``` [[NSDate alloc] init]; ``` で生成されるのは、`__NSDate`です。対して、 ``` [[NSDate alloc] initWithString:@"2015-09-06 00:00:00 +0000"]; ``` で生成されるクラスは`__NSTaggedDate`です。 ここからはフレームワークのプライベート領域なので推測でしかないのですが、`__NSTaggedDate`はタグ付きポインタで実装されているのだと思われます(同様の推察はいろいろ出てきます)。 タグ付きポインタを使うメリットは、ポインタの余った`bit`に日付情報を持たせることで、単一のインスタンスで複数の日付を表現できる、ヒープに優しい実装にできることです。