Reputation: 1499
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
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
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
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
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
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