A category to allow you to use the "switch/case"-like syntax with NSObjects (and not just integers/enums!)
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



This NSObject category allows you to use a "switch/case"-like syntax with any NSObject.

The use of swich/case is not limited to integers/enums anymore!

Basic Example

[someString switchCase:
 @"value1", ^{
     NSLog(@"The string someString is equal to value1!");
 @"value2", ^{
     NSLog(@"The string someString is equal to the other value value2!");
 @"", ^{
     NSLog(@"The string someString is empty!");
 }, nil];

Expected arguments

The switchCase: method takes a nil-terminated variable number of arguments, that needs to go by pairs (like in the dictionaryWithObjectsAndKeys: method for example).

The first argument is a value to be tested. The second argument is the block of code to be executed if the object (on which we called the switchCase: method) is equal to the preceding value. The next arguments continue the same way (test object, code block, test object, code block, ...) until the value nil is met.

  • The arguments with an odd position (first, third, fifth, ...) have to be id objects.
  • The arguments with an even position (second, fourth, sixth, ...) have to be blocks that does not take arguments and does not return a value (a.k.a. blocks of type dispatch_block_t), which simply means blocks with the syntax ^{ /* some code */ }.

Note: Be careful to respect these types: as with every methods having a variable number of arguments (like dictionaryWithObjectsAndKeys: and others) the parameters are not checked at compile-time. So parameters with the wrong type may lead to unexpected behavior or crashes at runtime.

Implementing the default: case

The switchCase: method returns YES if it has found an object equal to the target object (and thus has executed the corresponding code) and NO if none of the test objects were found equal to the target object.

This allows you to implement the equivalent of the "default:" statement by testing the return value of the switchCase: method, for example this (compact) way:

if(![someObject switchCase:
     comparisonObject1, ^{ NSLog(@"Case 1"); },
     comparisonObject2, ^{ NSLog(@"Case 2"); },
{ // default: 
    NSLog(@"Default: No case found!");

The global behavior of the switchCase: method is designed so that it returns as soon as an object is found equal to the target object (and its corresponding code is executed), without testing the values after the found one. This is the equivalent (compared to a standard C switch/case statement) of having a break; after each case:. It is thus guaranteed than no more than one block of code will be executed by the switchCase: method.

Using a different selector than isEqual:

The switchCase: method uses the isEqual: selector to compare the target object to the objects to be tested in the parameters.

An alternative method switchCaseWithComparisonSelector: is provided if you need to use a selector other than isEqual: for objects comparison. Its syntax is basically the same as switchCase:, except that you provide the @selector to use as the first parameter before the nil-terminated list of testObject/codeBlock pairs:

[[name lowercaseString] switchCaseWithComparisonSelector:@selector(isEqualToString:),
 @"firstname",  ^{ NSLog(@"This is FirstName"); },
 @"secondname", ^{ NSLog(@"Hello SecondName"); },
 @"thirdname",  ^{ NSLog(@"I am ThirdName"); },

The selector used must take a single parameter of type id and return a value of type BOOL (exactly as the isEqual: method and other isEqualToXXX: methods like isEqualToString:).

Integrate in your projects

Simply drag & drop the NSObject+ObjCSwitch.h and NSObject+ObjCSwitch.m files in your Xcode project.

Then, when you want to use the switchCase: method on any object, don't forget to import the header in your file (or you may instead add the #import "NSObject+ObjCSwitch.h in your Precompiled Header File (xxx-Prefix.pch) to avoid the need to import it everywhere in your source code).

Note: ObjCSwitch is compatible with both ARC and non-ARC projects (it does not create, retain or release any object anyway)