3

必要なすべてのアウトレット、ビュー、および制約を使用して、この UIViewController をストーリーボードにセットアップしました。完全。これを WatchStateController と呼びましょう。抽象親クラスとして機能します。

次に、アプリケーションの特定の状態に必要な機能を備えた WatchStateTimeController という WatchStateController のサブクラスを作成します。

UIStoryboard で 1 ビュー コントローラーを使用しようとしているため、WatchStateTimeController を WatchStateTimeController 型としてインスタンス化する際に問題が発生しています。WatchStateController としてインスタンス化されます。

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

WatchStateTimeController *timeController = (WatchStateTimeController *)[mainStoryboard instantiateViewControllerWithIdentifier:@"WatchStateController"];

これは、ストーリーボードの Identity Inspector の「Class」フィールドが「WatchStateController」に設定されているためです。問題は、実行時に Identity Inspector で設定されたこのクラス名を変更するにはどうすればよいかということです。

身元検査官

注:私がこれをやろうとしている理由を無視して、方法に集中してください。その理由をどうしても知りたい場合は、Strategy デザイン パターンを参照してください。

4

2 に答える 2

5

コメントで説明したように、ヘルパー オブジェクトを使用した戦略パターンの例を次に示します。

@class WatchStateController;

@protocol WatchStateStrategy <NSObject>
- (void)doSomeBehaviorPolymorphically:(WatchStateController *)controller;
@end

@interface WatchStateController
// or call this a delegate or whatever makes sense.
@property (nonatomic) id <WatchStateStrategy> strategy;
@end

@implementation WatchStateController
- (void)someAction:(id)sender
{
    [self.strategy doSomeBehaviorPolymorphically:self];
}
@end

@interface WatchStateTimeStrategy <WatchStateStrategy>
@end

@implementation WatchStateTimeStrategy
- (void)doSomeBehaviorPolymorphically:(WatchStateController *)controller
{
    // here's one variation of the behavior
}
@end

@interface WatchStateAnotherStrategy <WatchStateStrategy>
@end

@implementation WatchStateAnotherStrategy
- (void)doSomeBehaviorPolymorphically:(WatchStateController *)controller
{
    // here's another variation of the behavior
}
@end

View Controller を提示するときにこれを設定するには、(View Controller 自体のサブクラスを変更しようとするのではなく) 適切なヘルパー オブジェクトを割り当てます。

WatchStateController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"WatchStateController"];
if (useTimeStrategy) {
    viewController.strategy = [WatchStateTimeStrategy new];
} else {
    viewController.strategy = [WatchStateAnotherStrategy new];
}

View Controllerのサブクラス化と比較して、このアプローチの利点は次のとおりです。

  • これは、 SOLID の原則、特に単一責任の原則、オープン/クローズの原則などとより密接に連携しています。
  • テストを作成する予定がある場合、必要に応じて UI の依存関係がほとんどまたはまったくない可能性がある、小規模で焦点を絞ったヘルパー クラスにより、単体テストが容易になります。
  • これは、iOS で既に導入されている設計パターンと構造パターンにより厳​​密に従います (デリゲートを使用し、ストーリーボード/xib で通常の方法でビュー コントローラーをインスタンス化できるようにします)。
  • ビュー コントローラーからロジックを削除します。iOS では、ロジックが多すぎる大きなビュー コントローラーを簡単に取得できます。これを改善する機会を常に探すべきだと思います
于 2013-06-29T15:48:52.647 に答える