views:

246

answers:

2

I had a question regarding the use of asterisks in Objective-C. Just to be clear: I understand what pointers are and everything in procedural C. I was wondering two things though:

1) Why are all (references to) Objective-C objects pointers? Why not plain variables? (i.e. NSArray array = [[NSArray alloc] init];)

2) Why do you omit the asterisk when calling method?

Thanks!

+14  A: 

1) Why are all (references to) Objective-C objects pointers? Why not plain variables? (i.e. NSArray array = [[NSArray alloc] init];)

Think of an Objective-C object as a glorified struct for a moment.

NSArray array; in a local scope would be an object "allocated" on the stack. NSArray *array; indicates an object backed by a hunk of memory, typically allocated from the heap.

Long, long, ago it was decided that Objective-C wouldn't support objects on the stack. Mostly, because doing so would make memory management a gigantic mess (mainly, -retain of something on the stack doesn't make any sense at all).

Since Objective-C was designed as a pure superset of C and, unlike C++, doesn't try to modify the basic behavior of C, having the * in there seemed natural.

Note that id breaks this, but id is also a completely generic type. And it is, in fact, possible to have Objective-C objects on the stack. In Snow Leopard, Blocks are actually Objective-C objects and they do start on the stack. It isn't, however, supported for you to create your own objects on the stack.

2) Why do you omit the asterisk when calling method?

Because you aren't dereferencing the pointer to the object and that pointer to the object is critical within the method implementation itself. When you say...

[anArray objectAtIndex: 5];

... it is exactly equivalent to writing ...

objc_msgSend(anArray, @selector(objectAtIndex:), 5);

... and when you implement said method ....

- (id) objectAtIndex: (NSUInteger) anIndex;

... it is exactly equivalent to implementing this C function ...

id object_at_index(id self, SEL _cmd, NSUInteger anIndex) { ... }

That is, an Objective-C method is really just a C function that takes two or more arguments. As a matter of fact, you can paste this line of code into any method implementation and it'll "just work":

NSLog(@"method %@", NSStringFromSelector(_cmd));
bbum
Thanks for the great reply, Bill! Everything makes *perfect* sense!Quick follow-up question: Is there a good resource/book you can recommend for learning all the nitty-gritty aspects of this stuff? (Memory storage, etc.)Thanks again!
Rebecca Morgan
Apple's tutorials are a great place to start, but I'd also pick up a copy of Aaron Hilegass's Cocoa Programming. It's the textbook for the one-week courses he teaches.
NSResponder
+2  A: 

The Objective-C language defers as many decisions as it can from compile time and link time to runtime. Whenever possible, it dynamically performs operations such as creating objects and determining what method to invoke.
So if it allowed

NSArray array = [[NSArray alloc] init];  

in a method, then the compiler would have to know size of an NSArray at compile time.

yehnan