The key here is that you're dealing with an autorelease object. If a method name starts with init
, copy
, mutableCopy
or new
, you'll receive a non-autorelease object. This is not the case here (you are using dateWithTimeIntervalSinceNow
) and as a result, you'll receive an autorelease object.
Thus, you are instantiating an autorelease object and therefore it will not be deallocated until the autorelease pool is drained. And your weak reference will not be nil
-ed until the object is deallocated. The deallocation of autorelease objects happens when your app yields back to the run loop (or you explicitly create your own autorelease pool).
This not a question of the object being "a constant". And that other question you reference is discussing NSString
which, being heavily optimized, does not conform to traditional object memory management rules.
You can change the behavior by explicitly adding your own autorelease pool, which will cause the object to be deallocated when the pool is drained at the end of the @autoreleasepool
block, and you'll see your (null), (null)
response:
@autoreleasepool {
self.birthDay = [NSDate dateWithTimeIntervalSinceNow:0];
self.birthDay1 = self.birthDay;
self.birthDay = nil;
}
NSLog(@"_birthday1 is %@, %@", self.birthDay1 , self.birthDay);
You can also use a non-autorelease object (e.g. use a method whose name starts with init
) and this non-autorelease object will be deallocated immediately after being set to nil
:
self.birthDay = [[NSDate alloc] initWithTimeIntervalSinceNow:0];
self.birthDay1 = self.birthDay;
self.birthDay = nil;
NSLog(@"_birthday1 is %@, %@", self.birthDay1 , self.birthDay);
This will also show you (null), (null)
.