Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Macula

macrumors 6502
Original poster
Oct 23, 2006
434
21
All over the place
Hello folks,

I understand that it is at least a good practice in Obj-C and Cocoa to initialize all new class instances prior to first use:

NSString *myString;
myString = [[NSString alloc [init]];

If so, how can we understand the validity of a statement such as the following (without previous alloc and init calls):

NSString *myString = [anotherString uppercaseString];

Does the "equals" operator imply automatic calls to alloc and init? And if so, is this true for any class, or only for certain classes?

Thank you?
 
One of these is a - called on a new instance returned by alloc. The other is called a factory method. It is a + method called on the class. It will initialize the new Object for you.

-Lee
 
Hi Macula,
Your first example is creation of NSString Object and its initialization.

The scond example is: (As I understand it..)
That you assing to *myString "pointer" object that is a result generated by the uppercaseString method performed on anotherString object.

/piotr
 
NSString *myString;
myString = [[NSString alloc [init]];

This particular idiom is a poor practice. It assigns a zero-length string using a needlessly verbose statement, and creates an owned object which must be released.

You can get the same effect, i.e. a safe non-null string, with:
Code:
NSString *myString = @"";
Since string literals need not be released, nor are they dealloc'ed, you can release, autorelease, or not as desired.

One could also do this:
Code:
NSString *myString = nil;
The nil "non-object" does respond to messages, frequently responding with 0, so depending how it's used, this may also be a stand-in for an empty string.
 
Does the "equals" operator imply automatic calls to alloc and init? And if so, is this true for any class, or only for certain classes

The equals operator implies nothing. Your confusion stems from a concept called the autorelease pool. The method call in the second example returns an autoreleased object, whereas the first object is not autoreleased and must be explicitly released by you (because you allocated it).

I strongly recommend reading up on the autorelease pool and also on the naming convention that specifies which methods return autoreleased objects and which do not (i.e., allocXXX, newXXX, and copyXXX do not return autoreleased objects; all others do).
 
There is no implication in the "equals" operator. It is the same effect in C as it is in objective-C: get an argument (to the right of "=") and put its value into a variable.

+alloc returns an id value (untyped pointer). This value becomes the receiver for -init, which also returns an id. That value is placed into the lvalue (variable on the left). This is no different from any other C operation that returns a value.

In the second case, the returned value is a typed pointer (NSString*). The receiver performs the method operation, allocates an instance of NSString and initializes it with the result, then sends the result an -autorelease message (which means you do not have to worry about deallocating it yourself) and returns the result to be assigned to the variable (or perhaps used in a nested method as receiver, argument, whatever).

NSObject classes (provided by Apple) autorelease almost all of their return values, unless the method name contains "alloc", "new" or "copy", or if the documentation indicates otherwise. When you create a class (code methods for objects), it is probably best practice to adhere to the same standard when returning objects that are created by your methods so that you can keep things consistent. Then, if you have to come back and modify your code (or squash bugs), it will be easier to understand what is happening.

BTW, Lee is not correct, it is -uppercaseString, not +uppercaseString (because the receiver is not "NSString").
 
Wow, thank you all for taking the time to respond. It makes perfect syntactic sense to me now. With regard to the inner workings and the autorelease pool, I have only scratched the surface and will definitely do some better reading.

shouldn't the second line be:
myString = [[NSString alloc] init];

Oops… yes, of course. Thanks.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.