oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Strings in Cocoa, Part 2
Pages: 1, 2

Learning CocoaLearning Cocoa
By Apple Computer, Inc.
Table of Contents
Sample Chapter
Full Description
Read Online -- Safari

Mutable strings

Previously, in our discussion of NSString, I mentioned the fact that fundamentally strings in Cocoa are immutable arrays of Unicode characters. This means that once we create a string, we're stuck with it and there's nothing we can do about it with NSString anyway. NSMutableString is our solution. NSMutableString is a subclass of NSString that allows us to do exactly what we couldn't do before -- we can now create strings that posses the ability to modify and edit, or mutate, their contents.

Because NSMutableString is a subclass of NSString, everything we learned about strings in the previous column and this one holds true for mutable strings as well. In this section, I want to walk you through all of the methods that NSMutableString adds to NSString that allow us to edit the contents of mutable strings (I will refer to instances of NSString simply as strings, and instances of NSMutableString as mutable strings).

We have two methods that allow us to append a string to the end of an existing mutable string: They are - appendString: and - appendFormat:, and they work in the following way.

NSMutableString *aMutableString = [[NSMutableString alloc] initWithString:@"Hello"];
[aMutableString appendString:@", World!"];

The appendString message to aMutableString tells aMutableString to add the argument of the message to the end, so the resulting value of aMutableString is "Hello, World!". There are two things here to notice. First, we cannot use the @"..." construct to directly create mutable strings. Remember that this construct created strings that are compiled and are always present. Obviously we cannot change a pre-compiled string, so we have to create a new NSMutableString object like any other object, using alloc and an init method. We can however, use any of the init... methods declared in NSString, because that is the parent class of NSMutableString.

Additionally, note that none of the content-editing methods of NSMutableString return a value, their return type is void. These methods actually do change the value of the receiver string, rather than returning a modified copy of it, as we've become accustomed to with NSString methods.

We can also append a formatted string to the end of an existing string using -appendFormat:. This works exactly the same as the previous method, except you can format the string according to the rules we learned in the last column.

The method - deleteCharactersInRange: accepts a range (NSRange data type) as the sole argument and removes from the receiver string the characters that fall in that range. To make a range, the Foundation Framework provides the function (not a method of any class, a true C-type function) NSMakeRange(unsigned int location, unsigned int length), which takes two arguments that are the components of a range, and returns an NSRange variable. The first argument is the index of the first letter (think arrays -- counting starts from 0) and the second argument is the length of the range, inclusive of the first character. We could then remove the string we added in the previous example so we are left with the original string, "Hello":

NSRange aRange = NSMakeRange(5, 8);
[aMutableString deleteCharactersInRange:aRange];

Moving along with the methods of NSMutableString, we have - insertString: atIndex: which inserts the string given in the first argument into an index of the receiver given in the second argument. The characters in the receiver string that are at specified index and beyond all get displaced toward the end to make room for the inserted string. We would use this method like this:

NSMutableString *aMutableString = [[NSMutableString alloc] initWithString:@"Hello, World!";
[aMutableString insertString:@" (not goodbye)" atIndex:5];

which would transform aMutableString into "Hello (not goodbye), World!". Note that the first character of the word we are inserting is a space. Remember that arrays are indexed starting at index 0, so the "H" in aMutableString is at index 0.

If we want to completely change a string from one value to another, we can use the -setString: method. So we can take out the resulting string, aMutableString, from above and change it to whatever using this method:

[aMutableString setString:@"whatever."];

which makes aMutableString now hold the value "whatever.". This method should remind you of the set... methods we learned about in NSControl.

The final method we have in our mutable string toolbox is - replaceCharactersInRange: withString:, which does exactly what the method name says it will do. The first argument is a range indicating the characters you want to remove from the receiver string, and the second argument is a string which you want to put in their place -- just a straightforward replacement operation. Let's see how this works in code:

NSMutableString *aString = [[NSMutableString alloc] initWithString:@"Hello, World!";];
[aString replaceCharactersInRange:NSMakeRange(7,5) withString:@"Universe"];

And our original string "Hello, World" is changed to "Hello, Universe!".

String miscellany

Before the end of this column, I want to go over a few features of NSString that allow you to modify the case of a string in addition to obtaining numeric values from a string.

In the article about the color meter, we talked about the ability to take numerical values from an interface control by sending the object any of the following messages: intValue, doubleValue, and floatValue. The same is true for strings. That is, NSString responds to these exact messages in the same way as we learned for the interface controls (think polymorphism). The catch is that the string object can only be a number for these methods to work. We can't use these methods to pick a number out of a string. We can, however, find a number in a string, and then return its C-typed value. Suppose we have a string which has some text, and then a number after the text filling the remainder of the string. We could get it out in the following way:

NSString *textAndNumbers = @"Number of eggs in a dozen= 12";
NSString *numberPart = [textAndNumbers substringFromIndex:27];
int numberInADozen = [numberPart intValue];

I admit, this example is a bit contrived, but I imagine you get the idea here. Remember, we have to use the correct ...Value method according to the type of number in the string, and the destination data type.

One last tidbit of NSString madness I want to share with you are the methods that let us change the case of the text in the string: -capitalizedString, -lowercaseString, and - uppercaseString. -lowercaseString returns a string where every character of the receiver is in lowercase, -uppercaseString does the same except every character is converted to uppercase. The last of these three, -capitalizedString, is a little fancier, returning a string where the first letter of each word in the receiver string is converted to its uppercase counterpart. Here are these methods in action:

NSString *string = @"tHe uniVERSity of TEXAS";
NSString *lcstring = [string lowercaseString];
NSString *ucstring = [string uppercaseString];
NSString *capstring = [string capitalizedString];

These last three lines would convert string to "the university of texas", "THE UNIVERSITY OF TEXAS", and "The University Of Texas", in that order.

Final thoughts

In this column we just scratched the surface of Cocoa's string-handling ability. I've mentioned throughout the column that you should check out the NSString class reference (I hope you have the Foundation and Application Kit class reference pages bookmarked by now!) to get more detailed information about the other methods not discussed here. What I wanted to show you here are the basic ways of working with strings, giving you the confidence and the know-how to dig deeper into the dustier, more advanced parts of the NSString class. In the next column we will set ourselves to the task of learning how to develop good memory management habits.

Michael Beam is a software engineer in the energy industry specializing in seismic application development on Linux with C++ and Qt. He lives in Houston, Texas with his wife and son.

Read more Programming With Cocoa columns.

Return to the Mac DevCenter.