Objective-C Programming_ The Big Nerd Ranch Guide - Aaron Hillegass [45]
NSArray/NSMutableArray
When you add an object to an array, the array claims ownership of it. When you remove the object from the array, the array gives up ownership. Open BMITime, and take a look at how you are using the employees array. If we ignore all the other stuff, you see something like this:
// Create an array of Employee objects
NSMutableArray *employees = [[NSMutableArray alloc] init];
for (int i = 0; i < 10; i++) {
// Create an instance of Employee
Employee *person = [[Employee alloc] init];
// Put the employee in the employees array
[employees addObject:person];
}
[employees removeObjectAtIndex:5];
employees = nil;
You typically create an empty mutable array using alloc/init or the class method array. For example, you could have created the mutable array like this:
NSMutableArray *employees = [NSMutableArray array];
Note that the addObject: method adds the object to the end of the list. As objects are added, an array will grow as big as necessary to hold them.
Immutable objects
When you create an instance of NSArray, you assign all its objects to it when it is created. This typically looks like this:
NSArray *colors = [NSArray arrayWithObjects:@"Orange", @"Yellow", @"Green", nil];
The nil at the end is how you tell the method to stop. Thus, this colors array would only have three strings. (If you forget the nil, it will probably crash your program.)
Most beginning programmers are surprised by the existence of NSArray. Why would anyone want a list that can’t be changed? There are two reasons:
You don’t trust the people you work with. That is, you want to let them look at an array, but you don’t want them to be able change it. A gentler approach is to give them an NSMutableArray, but tell them it is an NSArray. For example, imagine the following method:
// Returns an array of 30 odd numbers
- (NSArray *)odds
{
static NSMutableArray *odds = [[NSMutableArray alloc] init];
int i = 1;
while ([odds count] < 30) {
[odds addObject:[NSNumber numberWithInt:i];
i += 2;
}
return odds;
}
Anyone calling this method assumes it is returning an immutable NSArray. If the caller tries to add or remove items from the returned object, the compiler will issue a stern warning – even though, it is, in fact, an instance of NSMutableArray.
The other reason is performance: an immutable object never needs to be copied. With a mutable object, you might make a private copy so that you know that no other code in the system can change it from underneath you. This is unnecessary for immutable objects. In fact, while the copy method of NSMutableArray makes a new copy of itself and returns a pointer to the new array, the copy method of NSArray does nothing – it just returns a pointer to itself.
As a result, immutable objects are fairly common in Objective-C programming. In Foundation, there are many classes that create immutable instances: NSArray, NSString, NSAttributedString, NSData, NSCharacterSet, NSDictionary, NSSet, NSIndexSet, and NSURLRequest. All of these have mutable subclasses: NSMutableArray, NSMutableString, NSMutableAttributedString, etc. NSDate and NSNumber, on the other hand, are immutable but don’t have mutable subclasses.
Sorting
There are several ways to sort an array, but the most common way is to use an array of sort descriptors. NSMutableArray has the following method:
- (void)sortUsingDescriptors:(NSArray *)sortDescriptors;
The argument is an array of NSSortDescriptor objects. A sort descriptor has the name of a property of the objects contained in the array and whether that property should be sorted in ascending or descending order. Why do we pass an