views:

115

answers:

5

I understand that the v03 example creates an object that I own and must ultimately release. What I would like to know is are there any differences between the first two(v_01 & v02), or are they essentially the same?

// Version_01
userName = @"Teddy";

// Version_02
userName = [NSString stringWithString:@"Gary"];

// Version_03
userName = [[NSString alloc] initWithString:@"Caroline"];
... some code
[userName release];

gary

A: 

The first two or essentially the same

The latter one is not however as userName would be an invalid string object at that point.

However changing it to

userName = [[[NSString alloc] initWithString:@"Caroline"] autorelease];

would render it effectively the same as the previous two.

Bryan McLemore
Why is the latter one an "invalid string object"? It looks perfectly valid to me - he allocates an NSString object, stores the initialized result in the userName variable, and releases it as needed.
Sbrocket
because on the next line he released it, at which point doing anything to it would result in a crash.
Bryan McLemore
I added the release to show that at some point later I was aware that the object would need releasing. Autorelease would probably have been a better way as you state, at least with that your less likely to forget to add the release and avoid a leak.
fuzzygoat
A: 

version 01: is a string constant.... version 02: is an auto-released NSString created by copying a constant.

kent
Not quiet, if you look at the memory address in a debugger you'll see that `username = @"bobDole"` and `username = [NSString stringWithString:@"bobDole"]` are actually pointers to the same string object.
Bryan McLemore
+4  A: 

They are all similar, but there are some slight differences between the three.

The first one is a pointer to a string constant. The string Teddy is stored in read-only memory, and userName is a pointer to this string constant. You need not (and cannot) retain or release this object, since it exists "permanently" (that is, for the duration of the program).

The second one is an autoreleased string object with the contents Gary. When returned to you, it has a release count of 0. It may be retained and released as needed.

The third one is similar to the second one, but it is not autoreleased, so it has a retain count of 1 when it is initially returned to you. Like the second one, it may be retained and released as needed.

mipadi
I would really wonder about the fact that the first one can't be released or retained as I've seen in my testing doing stringWithString: and a constant declaration result in pointers to the same memory address.
Bryan McLemore
Of course, all three are immutable strings and thus "constant" in that sense, but constant strings actually are slightly different in that they never go away.
Chuck
@Bryan: Doing `stringWithString:` with an immutable string very well might just return its argument. You actually can release and retain a constant string (otherwise you could never pass one to a setter method), but it has no effect.
Chuck
Yes, as Chuck noted, you can pass `retain` and `release` messages to a string constant, but they won't actually have an effect on the retaining of the object.
mipadi
It appears you're correct, it looks like all @"strings" are given an a special retainCount and can't be released/retained to any real affect. And yes `stringWithString:` as well as `copy` return `self` on string constants.
Bryan McLemore
Also worth noting I suppose that two subsequent constant string declarations both point at the same object (if the strings are the same of course)
Bryan McLemore
Yes, since `NSString` is immutable, it does a lot of optimizations behind the scenes to reduce memory usage.
mipadi
So in the 2nd example stringWithString you effectively get an object thats the same as the first example. (i.e. you can send retain or release to the object but nothing happens).
fuzzygoat
+1  A: 

Most of the differences in these instances is how the memory is managed. If you want a clearer view of what's happening in the background, you might want to peruse the Objective-C Memory Management Guide.

// Version_01
userName = @"Teddy";

This is a String constant that does not have any memory management associated with it. The memory used to hold the value is part of the memory in which the code resides in (essentially). retain and release calls on the variable will be ignored.

// Version_02
userName = [NSString stringWithString:@"Gary"];

This is an autoreleased instance of an NSString object. Its retain count is currently one and will be released by the autorelease pool soon unless it is retained.

// Version_03
userName = [[NSString alloc] initWithString:@"Caroline"];
[userName release];

This is a managed instance of an NSString. When it is first initialized, its retain count is one. After releasing it, the retain count went down to zero, therefore, its memory will be deallocated. Referring to the variable userName after releasing it will cause an EXE_BAD_ACCESS error.

Ben S
A: 

Practically, there are no differences, as long as you don't attempt to use the Version_03 string after you release it. If you want to do that, you'll need to autorelease it instead.

Peter Hosey