Now that we have a better handle on how object oriented programming works on iOS we should go over some of the key Foundation classes that you will use in your own apps. Like the name suggests, Foundation supports the key frameworks used in iOS development. Most of what you will be doing when building iOS apps comes from Foundation and will use Foundation classes.
Foundation Inheritance Hierarchy
Remember that classes can have an inheritance relationship with other classes. Although we did not mention it specifically we have already seen classes in Foundation that are in an inheritance relationship. The two classes that I am talking about are NSObject and NSString. NSString inherits from NSObject. You might also say that NSString is a kind of NSObject. Because of this relationship, NSString has all the properties and methods it needs to be and do what an object is.
If you look at all the object’s inheritance relationships as a whole you have what is called an inheritance hierarchy. It really helps to see the relationships between classes when you draw them out in a diagram. Below in Figure 1 is a diagram of the inheritance relationships that we have already covered in Foundation.
Let’s fill out more of this inheritance hierarchy with some key Foundation classes.
NSMutableString
In you look closely at the documentation and examples for NSString you will not find any way to change the content of the string itself. That is because NSString cannot be changed so there is no way to add characters or to edit NSString objects in any way. If you need to use a string that has values that change you must use NSMutableString.
NSMutableString inherits from NSString, but NSString has additional behavior that you can use to change the content of the string. If you were to view NSMutableString in the context of our inheritance hierarchy it would look like this:
The first thing that I want to do to demonstrate NSMutableString is change the UIAlertView code that I used as the Hello World example. What I will have now is two UIAlertView objects so when the user uses the app two separate boxes will pop up with messages. Each time the UIAlertView object appears it will display the content in our NSMutableString. Here is what the code should look like:
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:@"Alert View" message:@"Hello World" delegate:self cancelButtonTitle:@"Ok", nil otherButtonTitles:nil]; [alert1 show]; UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:@"Alert View" message:@"Hello World" delegate:self cancelButtonTitle:@"Ok", nil otherButtonTitles:nil]; [alert2 show];
When you build and run this project you will see two message boxes pop up, one right after another. Right now they will both still just say “Hello World” but next we will replace them with the contents of a NSMutableString object.
The first thing that we need to do is to instantiate a NSMutableString object. We can use a convenience method to do this for now.
NSMutableString *messageString = [NSMutableString stringWithString:@"Hello"];
Make sure to locate this object before the code used to create the two UIAlertView objects. Now let’s replace the text in the two UIAlertView objects with the NSMutableString object that we just created:
NSMutableString *messageString = [NSMutableString stringWithString:@"Hello"]; UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:@"Alert View" message:messageString delegate:self cancelButtonTitle:@"Ok", nil otherButtonTitles:nil]; [alert1 show]; UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:@"Alert View" message:messageString delegate:self cancelButtonTitle:@"Ok", nil otherButtonTitles:nil]; [alert2 show];
If you run this right now you will simply get two UIAlertViews that say “Hello”. What I want to do now is use appendString method to add “ World” to the hello world message. To do this we can send the appendString message to the messageString object right in between two UIAlertView objects.
NSMutableString *messageString = [NSMutableString stringWithString:@"Hello"];
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:@"Alert View"
message:messageString
delegate:self
cancelButtonTitle:@"Ok", nil
otherButtonTitles:nil];
[alert1 show];
[messageString appendString:@" World"];
UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:@"Alert View"
message:messageString
delegate:self
cancelButtonTitle:@"Ok", nil
otherButtonTitles:nil];
[alert2 show];
Now when you build and run the project the first UIAlertView object will pop up and say “Hello” and the second will say “Hello World”.
NSMutableString has more methods that you can use to alter the contents of the string: you can insert characters, delete characters and more.
NSArray
NSArray is a class that you can use when you want to work with a list of other objects. This is the object oriented version of the arrays that you were introduced to in the chapter on variables and arrays. The image below shows you how NSArray fits into the inheritance hierarchy. NSArray can only be used for objects (no primitive types like int or float allowed). Unlike the arrays you already have seen, NSArray has behaviors that can help you manage the objects contained in the array.
To create a NSArray object you must send the alloc and initWithObjects messages. initWithObjects requires a comma-separated list of objects and the last one must be nil. Let’s create an NSArray object right now:
NSArray *listOfStrings = [[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", nil];
If you are following along you can put this code right after the line of code where you created your NSMutableString object. Each of the strings in the code above (@”One”, @”Two”, @”Three”) are all NSString objects here. Using the @ compiler directive along with double quotes is a shortcut that you can use anytime that you need a temporary NSString object. The initWithObjects method requires a list of objects and the last object must be nil. We have not discussed nil yet, essentially nil is a reference to an empty object.
Now that you have this list of objects called listOfStrings you can access each of the members of this list using the objectAtIndex message. objectAtIndex requires us to send along a parameter to tell the NSArray object what object we want to reference. This parameter will be an integer that corresponds to the member of the array that we want. Let’s say we want to use the first and second members of listOfStrings in our UIAlertView objects. We could replace our NSMutableString object with an objectAtIndex message sent to listOfStrings.
NSMutableString *messageString = [NSMutableString stringWithString:@"Hello"]; NSArray *listOfStrings = [[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", nil]; UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:@"Alert View" message:[listOfStrings objectAtIndex:0] delegate:self cancelButtonTitle:@"Ok", nil otherButtonTitles:nil]; [alert1 show]; UIAlertView *alert2 = [[UIAlertView alloc] initWithTitle:@"Alert View" message:[listOfStrings objectAtIndex:1] delegate:self cancelButtonTitle:@"Ok", nil otherButtonTitles:nil]; [alert2 show];
When you Build and Run your project now the two UIAlertView objects will display the first and second members of your list. See the image below as an example:
For Each Loop
A really nice feature of NSArray is that you can use the for each loop. We already have three types of loops that we use in programming that we learned about in previous chapters: for, do and while loops. These loops all require used to either know how many actions we needed to take beforehand, how many elements were in the arrays were using or they required us to define some other condition to end the loop. For each loops don’t require any of these things and they are very easy to use.
The idea behind the for each loop is that the loop will do something for each member of the list. All you really need to do is set up a for statement that specifies that class definition of the objects in the list. For example, if I want to quickly write out each string in our listOfStrings object I could simply use a for each loop to do this in two lines of code:
for(NSString *s in listOfStrings) NSLog(@"%@", s);
We need to start out our for each loop with the keyword for and then put an expression in parenthesis that includes the class definition (NSString here), a temporary object variable *s, the keyword in and finally the NSArray object that we are looking at. The statement above will print something like this out to your console:
One Two Three
NSMutableArray
NSArray is great, but like NSString you cannot make any changes to NSArray objects once you create them. This means that you cannot add or remove objects from your lists. If you need a list that has the ability to add and remove objects then you must use NSMutableArray. NSMutableArray is a kind of NSArray and so has all the features of NSArray but with the additional of methods that allow adding and removing objects. See the image below to find out where NSMutableArray belongs in the Foundation inheritance hierarchy.
You can instantiate a NSMutableArray object in the same way as a NSArray object. There are actually a few ways to create objects like this, but the easiest way to create a NSMutableArray object is to simply use the alloc and init messages.
NSMutableArray *mutableListOfStrings = [[NSMutableArray alloc] init];
You can now start adding objects to this list. Just to demonstrate I am going to add some strings to mutableListOfStrings objects by using the addObject message.
NSMutableArray *mutableListOfStrings = [[NSMutableArray alloc] init]; [mutableListOfStrings addObject:@"One"]; [mutableListOfStrings addObject:@"Two"]; [mutableListOfStrings addObject:@"Three"];
You can use NSMutableArray objects like NSArray objects as well since NSMutableArray is an kind of NSArray. That means that you can use the for each loop with NSMutableArray so this would work in the same way as it did for the previous example.
NSMutableArray *mutableListOfStrings = [[NSMutableArray alloc] init];
[mutableListOfStrings addObject:@"One"];
[mutableListOfStrings addObject:@"Two"];
[mutableListOfStrings addObject:@"Three"];
for(NSString *s in mutableListOfStrings)
NSLog(@"%@", s);
You can also remove objects from NSMutableArray lists by using removeObjectAtIndex message. This message requires the position of the member object that you want to remove. So if you want to remove the second object in mutableListOfStrings then you need to pass the integer 1 as a parameter with this message.
NOTE: Arrays are indexed starting with the integer 0 so the first member in an array would be member 0, the second would be member 1 and so on.
Here is an example of how to remove an object from an NSMutableArray list:
[mutableListOfStrings removeObjectAtIndex:1];
You have some variations of this method that you can use as well as methods to insert objects as well. As always, it is a good idea to consult the documentation to get a full appreciation of what you can do with NSMutableArray.
Hands On Time
Create a NSMutableArray and add the names of five people that you know to the array. Next, look up the insertObject:AtIndex method to find out how to add your own name to the middle of the array. Finally, use a for each loop to go through your entire array. Add code to your for each loop to have a UIAlertView present each name.