PDA

View Full Version : Mutable Vs Immutable Strings




MadDoc
Mar 9, 2008, 03:44 PM
I can't quite get my head around the difference between these two concepts (I'm coming to Cocoa from REALbasic).

Apparently, you can't alter the value of an immutable string after it has been created. This excerpt is taken from this pdf book (http://www.cocoalab.com/BecomeAnXcoder.pdf):

Once you have initialized the variable, i.e. favoriteComputer, you may give the variable another value, but you can-
not change the string itself [5.7] because it is an instance of class NSString. More on this in a minute.

#import <foundation/foundation.h>
int main (int argc, const char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *favoriteComputer;
favoriteComputer = @"iBook"; // [5.7]
favoriteComputer = @"MacBook Pro";
NSLog(@"%@", favoriteComputer);
[pool release];
return 0;
}
When executed, the program prints:
MacBook Pro


How come the program prints MacBook Pro? If you can't change an immutable string then surely it would print what was initially assigned to it (i.e. iBook).

Sorry for such a dumb question!

MadDoc,



kainjow
Mar 9, 2008, 03:48 PM
It prints MacBook Pro because you're reassigning the pointer to a new NSString object. You aren't changing the original. NSMutableString allows you to alter the object that you create via methods such as appendString: and appendFormat:. You won't find those in the NSString base class.

bstreiff
Mar 9, 2008, 03:49 PM
I don't know much about ObjC, but it looks like all you're doing it pointing favoriteComputer from a string containing "iBook" to a string containing "MacBook Pro". You're not actually altering either string; they're immutable. The favoriteComputer variable is just a reference to a string. (Were favoriteComputer a constant, then you couldn't reassign it; thus it would always point to the "iBook" string.)

MadDoc
Mar 9, 2008, 05:56 PM
Oh I get it.

Does the original string object that contained "iBook" get destroyed then when the new object is created or do I have to do something about that (I'm using Garbage collection but even if I wasn't...)

MadDoc,

kainjow
Mar 9, 2008, 06:04 PM
If you're using GC, you don't need to worry about it.

If you're not, then you need to make sure the object is properly released if you created or retained it. There are plenty of articles/documentation on this if you want to know more.

MadDoc
Mar 9, 2008, 06:34 PM
Excellent, thanks for explaining!

One last (sort of) related question:

If you are using GC (I have read the Apple PDF on the subject), do you still need to use an AutoReleasePool or are they only required for manual memory management (obviously a lot more examples on the web were written before 10.5 and so couldn't use GC and thus all seem to use AutoReleasePools).

Thanks,

MadDoc,

kainjow
Mar 9, 2008, 06:38 PM
No you don't need it. However there is the NSGarbageCollector class which can be used to collect (dispose of) your GC objects - "for example after a loop in which you create a large number of temporary objects."

Also from Apple:

In a garbage collected environment, there is no need for autorelease pools. You can, though, use autorelease pools to hint to the collector that collection may be appropriate. In a garbage collected environment, sending a drain message to a pool triggers garbage collection if necessary (release, however, is a no-op). In a managed memory environment, drain has the same effect as release. Typically, therefore, if you write code that is intended to be compiled for garbage collected and managed memory environments, you should use drain instead of release.