2013-05-19 5 views
6

では、スイッチは数値のみを評価できます。私は、例えば、オブジェクトのクラスを比較するためにそれを使用できるように、このような何かが欲しい:では、単に数値ではなくクラスを評価するswitch文を作成するにはどうすればよいですか? Obj-Cのスイッチ

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

は、これを実現する方法はありますか?私は実際にスイッチを使用できるようにしたいのですが、これは異なるケースで読みやすく、今後どのようなケースでも追加することができるからです。何か案は?

+0

iPhoneを使用していると仮定すると、それぞれのサブビューに対して別々のviewControllerを使用していますか? –

+0

はい、それぞれのビューコントローラは1つです。実際、どのビューコントローラが現在表示されているのかを見たいと思います。私は簡単にそれを追跡することができます(グローバル、または何かなど)、int currentlyPresentedController = whateverなどの数値値を使用して、私はコントローラを切り替えるたびにそれを手動で値を設定するだけで、私はそのソリューションを非常に信頼していない値を設定することを忘れると、物事が悪くなる可能性があります。また、値は何らかの形で表示されている実際のコントローラと同期しなくなる可能性があります。より信頼できると思います。クラスを直接テストすることができます。 – TraxusIV

+0

明確にするために、この背後にある当初の動機は、「サイクル」ボタンがユーザによって押されたときに表示される一連のビューコントローラを循環することができるようにすることでした。クラスAのコントローラが現在表示されている場合は、Bに切り替えます。Bが表示されている場合はCなどに切り替えます。 – TraxusIV

答えて

9

このforum postで説明したように、あなたはLiskov Substitution Principleを適用したほうが良いと実際のクラスで<do stuff>ロジックを入れ、その後、あなたならば、これらすべてのクラスが継承するスーパークラスで共有する方法(またはOBJの-Cでのプロトコルを呼び出しますこの論理をまったく異なるクラスに分けて共有しようと計画している)。

これは、実装可能なすべての実装を心配する必要があるより高いレベルのクラスなしで、各実装/サブクラスのすべてのロジックをカプセル化します。これによりメンテナンス性が向上し、従来の手続き型プログラミングとは対照的に、オブジェクト指向プログラミングではより一般的です。

+0

+1素晴らしい答え。私はOPの本来の考え方は、オブジェクトのクラスに応じてView Controllerが一定の方法で応答することであると感じています。そのアプローチが許される時があるのですか、あるいは常にあなたは代替原理を守っていますか? –

+1

ありがとうございます。「ある意味で回答してください」と思うのは、クラスが全能なコントローラーではなく、何をすべきかを決めることを望んでいると思います。私はおそらくここで意図しているものにスイッチを使用しています - プリミティブ値の切り替え。私は大いにそれに依存していることを思い出しません:) –

+0

インテントは、実際にはView Controllerのタイプ間を循環することができます。タイプAの場合は現在のタイプBです。タイプBの場合は現在のタイプCなどですので、そのようなことは実際にはサブクラスではなくマスターコントローラクラスに属します。 – TraxusIV

0

それはできません。あなたは、私がswitch-case文が何をするかをシミュレートするためにisMemberOfClass:を使用して、この

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

} 

予告のようなif-elseifステートメントを使用する必要があります。しかし、あなたが使用したい場合はほとんどisKindOfClass:

1

switchステートメントは整数型でのみ動作します。大きなブロックif-elseが必要です。

実際にswitchステートメントを強制したい場合は、固定されたクラスの配列を使って何かを実行し、チェックしているクラスのインデックス位置からスイッチを切り離すことができます。しかし、case文での読みやすさのために、各クラスのインデックス位置を表す定数のセットを定義する必要があります。それは避けるために多くの仕事とコードを維持しており、ブロックするのはif-elseです。

0

辞書リテラルを使用できます。

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

注:これは楽しいことです。深刻な提案としてそれを取ってはいけません。

@AramKocharyan答えを真剣に使用してください。

+0

なぜクラスを直接使用しないのですか? –

+0

'Class'は' NSCopying'に準拠していません。 –

+0

あなたは正しいですが、これは本当です。[[NSObject class] respondsToSelector:@selector(copyWithZone :)] ' –

0

気になるクラスを値にマッピングするデータ構造を作成する方法の1つは、enumです。 これは多くのボイラープレートのコードになります。

Objective-Cには、Rubyなどの言語のような条件付きオブジェクトがありません。 C switchステートメントのみがあります。 C switchステートメントのcaseステートメントには整数定数が必要です。これがC switchステートメントを使用したよりダイナミックなアプローチを防止します。 C enum型は定数でも機能します。 これは、実行時にどちらも生成できないことを意味しますが、コンパイル時には発生する可能性があります。

C enumsとswitch文はうまく機能しますが、オブジェクトに対してはあまり役に立ちません。

ここで比較するには、化合物if-elseを実行する方が良いかもしれません。

関連する問題