As of the latest iOS SDK, calling [NSDate alloc] always returns the same memory location. You can verify this behavior with the following code:
NSDate *date1, *date2;
date1 = [NSDate alloc];
NSLog(@"date1: %p", date1);
date1 = [date1 init];
NSLog(@"date1: %p", date1);
date2 = [NSDate alloc];
NSLog(@"date2: %p", date2);
date2 = [date2 init];
NSLog(@"date2: %p", date2);
I suspect that it has to do with the fact that NSDate is a class cluster.
If the private subclasses of a class cluster have different storage requirements, it's impossible to know inside of alloc how much memory to allocate. One approach to solving this problem, and it appears this is the approach that Apple is using with NSDate, is to let the init and factory methods handle all the memory allocation, since those methods know what private subclass is actually going to be used.
At that point, all alloc is doing for you is allowing the user to preserve the [[NSDate alloc] init] pattern that's used for object creation everywhere in Objective-C. Since the memory location returned by alloc is always discarded, alloc may as well just return a fixed memory location, which is what it appears to be doing.