views:

389

answers:

4

Let's say I have a class declared as:

@class SomeClass

@interface SomeClass: NSObject {
  NSString *myString;
  NSString *yourString;
}

@end

And later, in some other code I say:

SomeClass *myClass = [[SomeClass alloc] init];

How does SomeClass know how much memory to allocate given that it didn't override +alloc? Presumably it needs storage for the ivars myString and yourString, but it's using +alloc inherited from NSObject. Is there reference material that covers these details?

+3  A: 

+[NSObject alloc] resolves to a call to the Objective-C runtime, which knows the size of each class.

kperryua
A: 

The alloc method does the equivalent of sizeof when it goes to create a new object. Also, the myString and yourString instance variables don't really have too much storage: they are merely pointers, so alloc just allocates enough memory to hold the addresses.

Quartz
It does not; sizeof is a compile time only operation. Allocation size is determined at runtime.
bbum
Yeah, myString and yourString don't have too much storage, but they have some, and it's significant, and it has to be allocated somewhere.
Rob Jones
myString and yourString are both exactly the size of a pointer in SomeClass.
bbum
@bbum, I know, I was replying to Quartz.
Rob Jones
I know that `sizeof` is a compile-time operation; Objective-C performs a check *similar* to `sizeof`.
Quartz
Actually, it doesn't. The size of the class's instances are determined at compile time. The modern ABI, though, allows a superclass to change size without breaking subclasses, requiring a bit of at-launch calculation. Finally, the class can dynamically resize instances at allocation as needed (see NSData and NSString).
bbum
@bbum, `sizeof` is not just a compile time only operation. If it is used on a variable length array (as permitted by C99), then it must return the size of that variable length array, and in many cases, can only known at runtime.
dreamlax
+12  A: 

+alloc is just a class method like any other. The default implementation in NSObject, uses class_getInstanceSize() to get the instance size that should be allocated. The instance size is determined based upon a combination of per-class (without inheritance) compile time structure size and per-runtime calculation of total size of the class and all superclasses. This is how non-fragile iVars are possible in 64 bit and the iPhone runtimes.

Some classes, class clusters in particular, don't actually do the true instance allocation until the initializer is called (which is why it is important to do self = [super init] in your initializer methods).

bbum
What are class clusters? Is this an Objective-C term I should be more familiar with?
Rob Jones
NSString is a class cluster, for example. When you create an NSString, you actually get an instance of whatever subclass is optimized to handle that particular type of string.
bbum
+2  A: 

Mike Ash wrote an article describing how some of this works:

Friday Q&A 2009-03-13: Intro to the Objective-C Runtime

Mike Akers
Very cool! Thanks for that.
Rob Jones