ViewControllerA.viewにボタンがあり、それをクリックするとViewControllerBがプッシュされるというシナリオを想定した場合、最もシンプルな書き方は以下のようになります:
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(100, 100, 100, 30);
[button setTitle:@"Button" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
- (void)buttonTapped
{
ViewControllerB *vc = [[ViewControllerB alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
この書き方で問題になるのは、ViewControllerA が ViewControllerB をインポートする必要があることです。依存関係が増えれば増えるほど、メンテナンスが面倒になり、循環依存関係が発生しやすくなります。
実装方法は次のとおりです。最初にプロトコルを定義し、このプロトコルに対応するクラスを登録する異議申し立てを通じて、必要なときに、プロトコルの対応するオブジェクトを取得することができます。これにより、特定のクラスに依存する必要がなくなります。これはしばしば「インターフェース指向プログラミング」と呼ばれます。
JSObjectionInjector *injector = [JSObjection defaultInjector]; // [1]
UIViewController <ViewControllerAProtocol> *vc = [injector getObject:@protocol(ViewControllerAProtocol)]; // [2]
vc.backgroundColor = [UIColor lightGrayColor]; // [3]
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
self.window.rootViewController = nc;
[ViewControllerAProtocol に対応するオブジェクトを取得します。
[このプロパティは ViewControllerAProtocol で定義されているため、警告は発生しません。
@interface ViewControllerAModule : JSObjectionModule
@end
@implementation ViewControllerAModule
- (void)configure
{
[self bindClass:[ViewControllerA class] toProtocol:@protocol(ViewControllerAProtocol)];
}
@end
バインディング操作は configure メソッドで行われ、オブジェクトに追加されると自動的に起動します。
JSObjectionInjector *injector = [JSObjection defaultInjector]; // [1]
injector = injector ? : [JSObjection createInjector]; // [2]
injector = [injector withModule:[[ViewControllerAModule alloc] init]]; // [3]
[JSObjection setDefaultInjector:injector]; // [4]
[1] デフォルトのインジェクターを取得
[2] デフォルトのインジェクタが存在しない場合は、新しいインジェクタを作成してください。
[3] モジュールをインジェクターに登録します。
[4] このインジェクターをデフォルトインジェクターに設定します。
このコードは+loadで直接実行できるので、AppDelegateで様々なModuleをインポートする必要がありません。
対応するクラスを直接取得することはできないため、外部で公開されるメソッドやプロパティはプロトコルで定義し、クラスもそのプロトコルを実装する必要があります。
@protocol ViewControllerAProtocol <NSObject>
@property (nonatomic) NSUInteger currentIndex;
@property (nonatomic) UIColor *backgroundColor;
@end
@interface ViewControllerA : UIViewController <ViewControllerAProtocol>
@end
各セクションは、異なる人々を担当することができ、その後、行に一緒に張ったが、また、MVC(Mess View Controller)の出現を避けるために、ある程度まで。
総合的に見ると、このlibは今でもかなり信頼性が高く、2年以上メンテナンスされていますし、使っているプロジェクトもいくつかあり、開発メンバーの効率化にもかなり役立つと思いますので、一度使ってみることを検討してみてはいかがでしょうか。
転載





