When using Objective-C Methods like compare:
and similar methods like caseInsensitiveCompare:
you should be aware of one possible problem:
compare:
on a nil-pointer!Why is that?
Because any method being called on a nil pointer returns nil.
Which is the same as 0 (zero).
Which is the same as NSOrderedSame.
Ouch!
Assume we have:
NSString *stringa = @"huhu";
NSString *stringb = @"huhu";
BOOL result = [stringa compare:stringb] == NSOrderedSame;
And print it out like this:
NSLog(@"[@\"%@\" compare:@\"%@\"] == NSOrderedSame is %@ ",
stringa, stringb, result ? @"yes":@"no");
Then we get:
[@"huhu" compare:@"huhu"] == NSOrderedSame is yes
If we call instead
stringb = @"not huhu";
result = [stringa compare:stringb] == NSOrderedSame;
We will get:
[@"huhu" compare:@"not huhu"] == NSOrderedSame is no
Of course, nobody warns us when we use a nil pointer instead:
stringa = nil;
result = [stringa compare:stringb] == NSOrderedSame;
Which of course results to:
[(null) compare:@"not huhu"] == NSOrderedSame is yes
Luckily, writing the code this way:
result = [stringb compare:stringa] == NSOrderedSame;
Results in the correct value again:
[not huhu compare:@"(null)"] == NSOrderedSame is no
Learnings?
So we learned: We need to check the left object, the method receiver, for not being nil to prevent strange results. And in cases, where we compare against a constant object, we might as well put the constant on the left hand side, resulting in e.g.
result = [@"huhu" compare:objectb] == NSOrderedSame;
to prevent stumbling over nil pointers.