Friday, November 27, 2009
iPhone Friday - November 27, 2009
Hello and Happy Gobble Gobble! I hope you all are recovering nicely from your tryptophan enduced food coma. Sorry for being late on this iPhone Friday as I too was feeling lethargic from a days worth of eating. So today I am posting the iPhone and iPod touch wallpapers - they are - sublime... Enjoy!
Tuesday, November 24, 2009
Objective-C Tuesdays: continue
See Also
Looping in Objective-C
Last week we looked at how to end a loop early using the Looping in Objective-C
break keyword. Today we will look at a similar action: how to skip to the next iteration.Sometimes you need to process each item in a collection or sequence, but some of those items get full processing and some don't. For example, you may want to skip empty strings in a collection. Frequently you do this using an
if...else statement:NSArray *collection = [NSArray arrayWithObjects: @"foo", @"", @"bar", @"baz", @"", nil];
int wordCount = 0;
for (NSString *item in collection) {
NSLog(@"found '%@'", item);
if (item.length > 0) {
wordCount++;
}
}
NSLog(@"word count = %d", wordCount);This is generally a good approach, but sometimes you have complex nested logic:NSArray *collection = [NSArray arrayWithObjects: @"foo", @"\n", @"bar", @"baz", @"", nil];
int wordCount = 0;
for (NSString *item in collection) {
NSLog(@"found '%@'", item);
if (item.length > 0) {
if ( ! [item isEqualToString:@"\n"]) {
wordCount++;
if (item.length < 4) {
NSLog(@"short word");
} else {
NSLog(@"long word");
}
}
}
}
NSLog(@"word count = %d", wordCount);The continue statement can help you simplify complicated cases like this by stopping the execution of the loop body for the current item and advancing to the next. Using continue, we can rewrite the example like this:NSArray *collection = [NSArray arrayWithObjects: @"foo", @"\n", @"bar", @"baz", @"", nil];
int wordCount = 0;
for (NSString *item in collection) {
NSLog(@"found '%@'", item);
if (item.length > 0) continue;
if ([@item isEqualToString:"\n"]) continue;
wordCount++;
if (item.length < 4) {
NSLog(@"short word");
} else {
NSLog(@"long word");
}
}
NSLog(@"word count = %d", wordCount);Like break, a continue statement only works on the innermost loop that encloses it:// outer loop
for (int i = 0; i < 10; i++) { // loop A
if (...) continue; // skips to next item in A
// inner loop
for (int j = 0; j < 10; j++) { // loop B
if (...) continue; // skips to next item in B
}
if (...) continue; // skips to next item in A
}The continue statement is most useful with a for or for...in loop, but can be used with a while and do...while loop with care. It's easy to create an infinite while loop using continue:NSArray *collection = [NSArray arrayWithObjects: @"foo", @"", @"bar", @"baz", @"", nil];
int wordCount = 0;
int i = 0;
while (i < collection.count) {
NSString *item = [collection objectAtIndex:i];
NSLog(@"found '%@'", item);
if (item.length > 0) {
continue; // OOPS! forgot to increment i
}
wordCount++;
i++;
}
NSLog(@"word count = %d", wordCount);This loop will reach the second item in the collection and get stuck there -- it never reaches the i++ at the end of the loop body. The solution is simple:NSArray *collection = [NSArray arrayWithObjects: @"foo", @"", @"bar", @"baz", @"", nil];
int wordCount = 0;
int i = 0;
while (i < collection.count) {
NSString *item = [collection objectAtIndex:i];
NSLog(@"found '%@'", item);
if (item.length > 0) {
i++;; // move to next item
continue;
}
wordCount++;
i++;
}
NSLog(@"word count = %d", wordCount);This is a consequence of the free-form nature of the while and do...while loops. The compiler knows how to make a for or for...in loop advance to the next item, but the other loops leave that up to you; continue acts more like a special goto statement with while and do...while loops.Next time, we'll look at the mother of all loops, the
goto statement.
Friday, November 20, 2009
Tuesday, November 17, 2009
Objective-C Tuesdays: break out of a loop
Last week we finished looking at the four looping statements in Objective-C: the
Sometimes you want to stop a loop prematurely. A common example of this is when you need to iterate over an unsorted collection or array looking for an item:
You can use a boolean flag variable to indicate when you're done:
You can use
Next week we will look at the other loop flow modifier,
for loop, the Objective-C 2.0 for...in loop, the while loop and the do...while loop. Today we'll look at how you break out of a loop early.Sometimes you want to stop a loop prematurely. A common example of this is when you need to iterate over an unsorted collection or array looking for an item:
NSArray *collection = [NSArray arrayWithObjects:@"foo", @"a", @"bar", @"baz", @"b", nil];
for (NSUInteger i = 0; i < collection.count; i++) {
NSString *item = [collection objectAtIndex:i];
NSLog(@"Checking item '%@'", item);
if (item.length == 1) {
NSLog(@"Found single letter at index %u", i);
/* no need to look at the rest -- we can stop now */
}
}Once you find the item you're looking for, there's no need to finish the loop. In fact, if you search the whole collection, you will always find the last item that matches your criteria, which isn't always what you want.You can use a boolean flag variable to indicate when you're done:
NSArray *collection = [NSArray arrayWithObjects:@"foo", @"a", @"bar", @"baz", @"b", nil];
BOOL foundFirst = NO;
for (NSUInteger i = 0; i < collection.count && ! foundFirst; i++) {
NSString *item = [collection objectAtIndex:i];
NSLog(@"Checking item '%@'", item);
if (item.length == 1) {
NSLog(@"Found first single letter at index %u", i);
foundFirst = YES;
}
}This approach works, but is somewhat complicated and error-prone. A nicer way to exit a loop early is to use the break keyword. Using break, the example becomes:NSArray *collection = [NSArray arrayWithObjects:@"foo", @"a", @"bar", @"baz", @"b", nil];
for (NSUInteger i = 0; i < collection.count; i++) {
NSString *item = [collection objectAtIndex:i];
NSLog(@"Checking item '%@'", item);
if (item.length == 1) {
NSLog(@"Found first single letter at index %u", i);
break;
}
}When the break statement is encountered, loop processing is stopped and execution resumes with the first statement after the loop; you can think of break as a sort of return statement for loops.You can use
break to exit any of the loop statements. If we don't care about the index of the first item, we can simplify the example further by using the for...in loop:NSArray *collection = [NSArray arrayWithObjects:@"foo", @"", @"bar", @"baz", @"", nil];
for (NSString *item in collection) {
NSLog(@"Checking item '%@'", item);
if (item.length == 1) {
NSLog(@"Found first single letter");
break;
}
}The break statement only works on the innermost loop that encloses it:// outer loop
for (int i = 0; i < 10; i++) {
if (...) break; // skips to A
// inner loop
for (int j = 0; j < 10; j++) {
if (...) break; // skips to B
}
// B
}
// AThe first break statement is inside the outer loop, and will skip to A. The second break statement is inside the inner loop; it skips to B, ending the inner loop but staying inside the outer loop.Next week we will look at the other loop flow modifier,
continue statement.
Tuesday, November 10, 2009
Objective-C Tuesdays: the do...while loop
Last time we looked at the
Unlike the
The
The
while loop. Today we'll examine it's sibling the do...while loop.Unlike the
while loop, the do...while loop is guaranteed to execute the loop body at least once. The loop condition is checked at the end of each loop iteration.The
do...while loop starts with the keyword do followed by a single statement or block that makes up the body of the loop. The loop body is followed by the keyword while and parentheses containing the condition with a semicolon at the end.The
do...while loop is almost always written on three or more lines, and almost always with a block instead of a single statement./* do...while loop with a single statement */
do
statement;
while (condition);
/* do...while loop with a block */
do {
block;
} while (condition);
Initialization of the loop counter or other loop variables must be done before the do...while statement; this often means declaring and initializing a local variable:int i = 0;
do {
/* ... */
} while (i < 10);
When using a loop counter, it's important to remember to advance the counter to the next value in the body of the loop. For instance, to log the numbers 0 through 9:
int i = 0;
do {
NSLog(@"%d", i);
i++; /* advance the loop counter */
} while (i < 10);
If you forget to advance the loop counter, you'll create an infinite loop.
int i = 0;
/* warning, infinite loop, i is always 0 */
do {
NSLog(@"%d", i);
/* oops, forgot to increment i */
} while (i < 10);
The key thing that differentiates the do...while loop from the while loop is that it always executes the loop body at least once; the while loop doesn't guarantee that. An example of this difference:
BOOL looping = NO;
NSLog(@"before while loop:");
while (looping) {
NSLog(@" executing the while loop");
}
NSLog(@"after while loop:");
NSLog(@"before do...while loop:");
do {
NSLog(@" executing the do...while loop");
} while (looping);
NSLog(@"after do...while loop:");The output of these two loops looks like this:
before while loop: after while loop: before do...while loop: executing the do...while loop after do...while loop:Next week, we'll look at using
break to break out of a loop.
Subscribe to:
Comments (Atom)






















