PTTHomps
PTTHomps

Reputation: 1499

in Obj-C, how could I make a switch statement that will evaluate classes, rather than just numbers?

in Obj-C a switch can only evaluate numbers. I'd like to be able to use it to compare classes of objects, something like this, for instance:

switch (currentSubViewController.class) 
{
     case UITableViewController.class :
          <do stuff>
          break;
     case UICollectionViewController.class :
          <do stuff>
          break;
}

Is there any way to achieve this? I'd really like to be able to use a switch because it makes it so easy to read for different cases, and I can add more cases at any point in the future. Any ideas?

Upvotes: 7

Views: 3315

Answers (5)

uchuugaka
uchuugaka

Reputation: 12782

One way is to build a data structure mapping the classes you care about to values in an enum. This will be a lot of boiler plate code.

Unfortunately, Objective-C has no object oriented switch conditional like languages such as Ruby. It only has the C switch statement. A case in the C switch statement requires an integer constant and this is what prevents more dynamic approaches using C switch statements. The C enum type also works with constants. This means neither one can be generated at runtime, but could be at compile time.

C enums and switch statements work well together but not so hot for objects.

So, you might be better off doing compound if-else statements to do your comparisons here.

Upvotes: 0

Jeffery Thomas
Jeffery Thomas

Reputation: 42598

You can use a dictionary literal.

((void(^)())@{
NSStringFromClass([UITableViewController class]) : [^{
    // stuff
} copy],
NSStringFromClass([UICollectionViewController class]) : [^{
    // stuff
} copy]
}[NSStringFromClass([currentSubViewController class])])();

NOTE: This is just for fun. Please don't take it as a serious suggestion.

Seriously use @AramKocharyan answer.

Upvotes: 0

rmaddy
rmaddy

Reputation: 318884

The switch statement only works with integer types. You need a big if-else block.

If you really want to force a switch statement then you could work out something using a fixed array of classes and base the switch off of the index position of the class you are checking. But for readability in the case statements, you would need to define a set of constants representing the index position of each class. That's a lot of work and code to maintain just to avoid and if-else block.

Upvotes: 1

Bryan Chen
Bryan Chen

Reputation: 46608

Thats not possible. You have to use if-elseif statement like this

if ([currentSubViewController isMembefOrClass:[UITableViewController class]]) 
{
    <do stuff>
} else if ([currentSubViewController isMemberOfClass:[UICollectionViewController class]]) {

}

notice that I use isMemberOfClass: to simulate what switch-case statement will do. But in most of the cases you want to use isKindOfClass:

Upvotes: 0

Aram Kocharyan
Aram Kocharyan

Reputation: 20431

As described in this forum post you would be better off applying the Liskov Substitution Principle and put the <do stuff> logic in the actual class, and then call a method shared by a superclass all these classes inherit (or a protocol in Obj-C if you're planning to have this logic shared across totally different classes).

This encapsulates all the logic in each implementation/sub-class without a higher level class needing to worry about every single possible implementation you might have. This improves maintainability and is more common in Object Oriented Programming as opposed to plain old procedural programming.

Upvotes: 9

Related Questions