Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

alloc + init memory usage mechanism

I am just curious to know when an object has made by alloc, and a piece of memory allocated to it, why init don't use that piece of memory and changes the address of object?

NSDate *t = nil;
NSLog(@"t = %p",t); // t = 0x0 

t = [NSDate alloc];
NSLog(@"t = %p",t); // t = 0x100107af0

t = [t init];
NSLog(@"t = %p",t); // t = 0x1001035a0
like image 868
Hadi Avatar asked Dec 22 '13 11:12

Hadi


2 Answers

Two-step initialization allows us to do these kinds of things (namely, substituting an instance of a class for another depending on the initializer called). Class clusters all over Foundation and UIKit take advantage of this to return instances optimized for a particular use-case. For example, UIColor itself is just an interface for its subclasses that implement color caching (all the named initializers like +blackColor), the RGB color space (+colorWithRed:green:blue:alpha), the black and white color space (+colorWithWhite:alpha:), CIColor compatibility, etc. And so NSDate is too. When you call -init, Apple has means and motive to return a different object that implements the same interface as NSDate as an optimization because you honestly shouldn't care what you get as long as it doesn't launch the missiles when you try to message it properly.

like image 128
CodaFi Avatar answered Nov 24 '22 21:11

CodaFi


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.

like image 39
godel9 Avatar answered Nov 24 '22 20:11

godel9