Objective-C Programming_ The Big Nerd Ranch Guide - Aaron Hillegass [31]
}
}
return 0;
}
Programmers do this so often that they made a special addition to the for-loop for iterating over arrays. Edit the code to use this mechanism:
#import int main(int argc, const char * argv[]) { @autoreleasepool { // Create three NSDate objects NSDate *now = [NSDate date]; NSDate *tomorrow = [now dateByAddingTimeInterval:24.0 * 60.0 * 60.0]; NSDate *yesterday = [now dateByAddingTimeInterval:-24.0 * 60.0 * 60.0]; // Create an array containing all three (nil terminates the list) NSArray *dateList = [NSArray arrayWithObjects:now, tomorrow, yesterday, nil]; for (NSDate *d in dateList) { NSLog(@"Here is a date: %@", d); } } return 0; } This type of loop is known as fast enumeration, and it is an extremely efficient way to walk through the items in an array. There is one restriction: you may not add to or remove from the array while enumerating over it. NSMutableArray An instance of NSArray is created with a list of pointers. You can never add or remove a pointer from that array. An instance of NSMutableArray is similar to an instance of NSArray, but you can add and remove pointers. (NSMutableArray is a subclass of NSArray. More about subclasses in Chapter 18.) Change your example to use an NSMutableArray instance and methods from the NSMutableArray class: #import int main(int argc, const char * argv[]) { @autoreleasepool { // Create three NSDate objects NSDate *now = [NSDate date]; NSDate *tomorrow = [now dateByAddingTimeInterval:24.0 * 60.0 * 60.0]; NSDate *yesterday = [now dateByAddingTimeInterval:-24.0 * 60.0 * 60.0]; // Create an empty array NSMutableArray *dateList = [NSMutableArray array]; // Add the dates to the array [dateList addObject:now]; [dateList addObject:tomorrow]; // Put yesterday at the beginning of the list [dateList insertObject:yesterday atIndex:0]; for (NSDate *d in dateList) { NSLog(@"Here is a date: %@", d); } // Remove yesterday [dateList removeObjectAtIndex:0]; NSLog(@"Now the first date is %@", [dateList objectAtIndex:0]); } return 0; } Challenges This next challenge is, well, more challenging. Read through the following program, which finds common proper names that contain two adjacent A’s. #import int main (int argc, const char * argv[]) { @autoreleasepool { // Read in a file as a huge string (ignoring the possibility of an error) NSString *nameString = [NSString stringWithContentsOfFile:@"/usr/share/dict/propernames" encoding:NSUTF8StringEncoding error:NULL]; // Break it into an array of strings NSArray *names = [nameString componentsSeparatedByString:@"\n"]; // Go through the array one string at a time for (NSString *n in names) { // Look for the string "aa" in a case-insensitive manner NSRange r = [n rangeOfString:@"AA" options:NSCaseInsensitiveSearch]; // Was it found? if (r.location != NSNotFound) { NSLog(@"%@", n); } } } return 0; } The file /usr/share/dict/propernames contains common proper names. The file/usr/share/dict/words contains regular words (not proper names). Now write a program based on the one above that finds common proper names that are also regular words. For example, “Glen” is a guy’s name, and “glen” is a narrow valley. When a computer orders strings, it typically considers uppercase letters as coming before lowercase letters. To do a comparison that ignores the case, use the method caseInsensitiveCompare:. NSString *a = @"ABC"; NSString *b = @"abc"; if ([a caseInsensitiveCompare:b] == NSOrderedSame) { NSLog(@"a and b are equal"); } if ([a caseInsensitiveCompare:b] == NSOrderedAscending) { NSLog(@"a comes before b"); } if ([a caseInsensitiveCompare:b]
Arrays come in two flavors:
Create a new Foundation Command Line Tool named Groceries. Start by creating an empty NSMutableArray object. Then add several grocery-like items to the array. (You’ll have to create those, too.) Finally, use fast enumeration to print out your grocery list.