When A Café Is Not A Café – A Short Lesson In Unicode Featuring NSString

on March 8th, 2012 by Tom 1 Comment Cocoa, Coding Tips

Let’s start with two exotic strings (console output is in the code comments):

NSString* apples = NSGetFrenchWord();
NSString* oranges = NSGetFrenchWord();

NSLog(@"apples == '%@'", apples); 
//apples == 'café'
NSLog(@"oranges == '%@'", oranges); 
//oranges == 'café'

They look identical, but looks can be deceiving.

NSLog(@"isEqual? %@", [apples isEqual:oranges] ? @"YES" : @"NO");
//isEqual? NO
NSLog(@"[apples length] == %lu", [apples length]);
//[apples length] == 4
NSLog(@"[oranges length] == %lu", [oranges length]);
//[oranges length] == 5

Read full post →

Const Correctness For NSString (And Pointers In General)

on December 16th, 2011 by Tom Cocoa, Coding Tips

So you’re implementing a new notification and you want the name to be a constant. Easy, right?

const NSString* VTMyNewNotification;

If that’s how you do constants, you’re not doing it quite right. Try assign a new value to the alleged constant and watch in horror as the compiler doesn’t stop you.

This is because when you type const NSString*, the compiler interprets that as a pointer to a constant NSString. NSString is already an immutable object, so making a constant NSString doesn’t do anything except maybe cause some compiler errors/warnings later when you try to use it. What you’re really after is a constant pointer to an NSString. It’s ever so subtly different, and written like so:

NSString* const VTMyNewNotification;

Don’t feel bad. It’s a common mistake. I used to do it until Rob Napier schooled me, and now I’m passin’ on the learnin’ to you.

Coding Tip: Replace Complicated Conditions With Boolean Variables

on October 3rd, 2009 by Tom Coding Tips

Consider the following if statement:

if(dragOperation != NSDragOperationCopy && NSPointInRect(currentMouseLocation, self.bounds)){
    //do something
}

Even though you may have worked out what the condition represents, it probably took you a little longer than it should. It’s complicated, making it time consuming to read, and prone to bugs upon modification. Thankfully, there is an easy remedy:
Read full post →

Coding Tip: Use The Ternary Conditional Operator

on September 9th, 2009 by Tom Coding Tips

The ternary conditional operator (?:) can be used as a short-hand version of an if statement. It is a feature of many languages.

For example, this code:

int height;
if(isTall)
    height = 50;
else
    height = 10;

can be better written as:

int height = isTall ? 50 : 10;

The ?: operator is good for replacing very simple if statements, but is bad for complicated if statements as it can harm readability.

Coding Tip: Don’t Mix Abstraction Levels

on July 5th, 2009 by Tom Coding Tips

Can you tell what is wrong with the abstraction in this class interface?

@interface EmployeeList
-(void) addObject:(Employee*)anEmployee;
-(void) removeObject:(Employee*)anEmployee;
-(NSUInteger) numberOfEmployees;
@end

Here is the answer:
Read full post →

Coding Tip: Have A Single Exit Point

on June 30th, 2009 by Tom 6 Comments Coding Tips

Having one exit point (return) from a function is a good thing. Here is an example of a single exit point:

int MyArray::indexOfElement(int elementToFind){
	int foundIndex = ELEMENT_NOT_FOUND;

	for(int i = 0; i < m_numberOfElements; ++i){
		if(this->elementAtIndex(i) == elementToFind){
			foundIndex = i;
			break;
		}
	}

	return foundIndex;
}

Having multiple exit points can be bad. Here is an example of multiple exit points:

int MyArray::indexOfElement(int elementToFind){
	for(int i = 0; i < m_numberOfElements; ++i){
		if(this->elementAtIndex(i) == elementToFind){
			return i;
		}
	}

	return ELEMENT_NOT_FOUND;
}

Why are multiple exit points bad? Because I say so. They are also bad for these two reasons:

Read full post →