3

XIB を使用して View Controller に挿入されたプロパティを取得できませんinitWithNibName:bundle:

例:

これは私のアセンブリです:

@implementation AppAssembly

- (ViewControllerC *)viewControllerC
{
    return [TyphoonDefinition withClass:[ViewControllerC class]
                          configuration:^(TyphoonDefinition *definition) {
      [definition injectProperty:@selector(name) with:@"Injected string"];
    }];
}

@end

ViewControllerA コード:

@implementation ViewControllerA

- (IBAction)buttonAction:(id)sender 
{
    ViewControllerB *viewControllerB = [[ViewControllerB alloc] initWithNibName:@"ViewControllerB" bundle:nil];
    [self.navigationController pushViewController:viewControllerB animated:YES];
}

@end

ViewControllerB コード:

@implementation ViewControllerB

- (IBAction)buttonAction:(id)sender 
{
    ViewControllerC *viewControllerC = [[ViewControllerC alloc] initWithNibName:@"ViewControllerC" bundle:nil];
    [self.navigationController pushViewController:viewControllerC animated:YES];
}

@end

ViewControllerC コード:

@interface ViewControllerC : UIViewController

@property (copy, nonatomic) NSString *name;

@end

@implementation ViewControllerC

- (void)viewDidLoad 
{
    [super viewDidLoad];

    // Why is this not being injected?
    self.title = self.name;
}

@end

AppDelegate コード:

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ViewControllerA *rootViewController = [[ViewControllerA alloc] initWithNibName:@"ViewControllerA" bundle:nil];
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = navigationController;
    [self.window makeKeyAndVisible];

    return YES;
}

@end

私はすでにサンプルをチェックしましたが、それらはこのアプローチとは異なります。私が間違っていることを教えてください。

ありがとう。

4

2 に答える 2

1

Typhoon は依存性注入コンテナーです。つまり、インストルメント化、スウィズル、またはその他の方法でクラスに影響を与えることはありません。したがって、依存関係が注入されたクラスのインスタンスを取得するには、Typhoon に問い合わせる必要があります。

ストーリーボードではないのはなぜですか?

plist 統合を使用する場合、Typhoon は UIStoryboard の代わりに TyphoonStoryboard を登録し、ストーリーボードの定義に基づいてインスタンスを発行します。通常のストーリーボードと同じように機能し、依存関係が注入されるという追加の利点があります。

他の場所では、依存関係が注入されたインスタンスを取得するために、アセンブリ インターフェイスを使用し、Typhoon に問い合わせます。

解決策の手順:

アセンブリに ViewControllerB の定義を追加します。(Objective-C では、必要に応じて自動注入マクロを使用することもできます)。

- (ViewControllerB *)viewControllerB
{
    return [TyphoonDefinition withClass:[ViewControllerB class] 
        configuration:^(TyphoonDefinition *definition) {

        [definition useInitializer:@selector(initWithNibName:bundle:) 
            parameters:^(TyphoonMethod *initializer) {

            [initializer injectParameterWith:@"ViewControllerB"];
            [initializer injectParameterWith:[NSBundle mainBundle]];
        }];

        [definition injectProperty:@selector(assembly) with:self];
    }];
}

プロパティを ViewControllerB に追加します。

//Start with this, next task is to back this with a protocol
@property(nonatomic, strong) AppAssembly *assembly;

ViewControllerC をインスタンス化するボタン アクションを変更します。

ViewControllerC *viewControllerC = self.assembly.viewControllerC
[self.navigationController pushViewController:viewControllerC animated:YES];

アプリケーション クラスが TyphoonAssembly に依存するようになりました。これが必要ない場合はどうすればよいですか?

すべての Typhoon アセンブリはプロトコルによってサポートされるため、アプリケーションはインスタンスのプロバイダーのみを認識し、Typhoon は認識しません。Typhoon からの移行を希望する場合は、そのプロトコルの代替実装を提供するだけで、堅牢なアーキテクチャがそのまま残ります。

于 2015-07-20T01:47:45.413 に答える
0

そのため、最初に AppAssembly に、アセンブリが挿入された viewControllerB のインスタンスを要求する必要があり、それを使用して viewControllerC のインスタンスを取得することができました。

AppAssembly コード:

- (ViewControllerB *)viewControllerB
{
    return [TyphoonDefinition withClass:[ViewControllerB class]
                          configuration:^(TyphoonDefinition *definition) {
                              [definition useInitializer:@selector(initWithNibName:bundle:)
                                              parameters:^(TyphoonMethod *initializer) {
                                                  [initializer injectParameterWith:@"ViewControllerB"];
                                                  [initializer injectParameterWith:nil];
                                              }];

                              [definition injectProperty:@selector(assembly) with:self];
                          }];
}

- (ViewControllerC *)viewControllerC
{
    return [TyphoonDefinition withClass:[ViewControllerC class]
                          configuration:^(TyphoonDefinition *definition) {
                              [definition useInitializer:@selector(initWithNibName:bundle:)
                                              parameters:^(TyphoonMethod *initializer) {
                                                  [initializer injectParameterWith:@"ViewControllerC"];
                                                  [initializer injectParameterWith:nil];
                                              }];

                              [definition injectProperty:@selector(name) with:@"Injected string"];
    }];
}

ViewControllerA コード:

@implementation ViewControllerA

- (IBAction)buttonAction:(id)sender
{
    ViewControllerB *viewControllerB = [[[AppAssembly new] activate] viewControllerB];
    [self.navigationController pushViewController:viewControllerB animated:YES];
}

@end

ViewControllerB コード:

@implementation ViewControllerB

- (IBAction)buttonAction:(id)sender 
{
    ViewControllerC *viewControllerC = [self.assembly viewControllerC];
    [self.navigationController pushViewController:viewControllerC animated:YES];
}

@end

ViewControllerC コード:

@implementation ViewControllerC

- (void)viewDidLoad 
{
    [super viewDidLoad];
    self.title = self.name;
}

@end

ご覧のとおり、これを行うViewControllerB *viewControllerB = [[[AppAssembly new] activate] viewControllerB];必要がありました。別の方法があるかどうかはわかりません。そのおかげで、ViewControllerB にアセンブリを挿入することができたので、これを行うことができましViewControllerC *viewControllerC = [self.assembly viewControllerC];ViewControllerC *viewControllerC = [[[AppAssembly new] activate] viewControllerC];。とにかく、少なくとも 1 回は new を呼び出してアクティブ化する必要があったと思います。

ありがとう。

于 2015-07-23T15:19:13.613 に答える