TyphoonComponentFactory

TyphoonComponentFactory

我正在使用Typhoon进行依赖注入。但是我有一个问题。有时,我会收到以下异常:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'No component matching id 'nemIdStoryboard'.'

发生此异常的代码如下所示:
class PaymentApproveViewController : UIViewController {
   var assembly : ApplicationAssembly!
   //...
   private func signPayment() {
      let storyboard = assembly.nemIdStoryboard()
      let controller = storyboard.instantiateInitialViewController() as NemIDViewController
   //...
   }
}

我的汇编代码如下所示:
public dynamic func rootViewController() -> AnyObject {
    return TyphoonDefinition.withClass(RootViewController.self) {
        $0.injectProperty("assembly", with: self)
    }
}

public dynamic func paymentApproveViewController() -> AnyObject {
    return TyphoonDefinition.withClass(PaymentApproveViewController.self) {
        $0.injectProperty("assembly", with: self)
    }
}
public dynamic func nemIdStoryboard() -> AnyObject {
    return TyphoonDefinition.withClass(TyphoonStoryboard.self) {
        $0.useInitializer("storyboardWithName:factory:bundle:") {
            $0.injectParameterWith("NemID")
            $0.injectParameterWith(TyphoonBlockComponentFactory(assembly:self))
            $0.injectParameterWith(nil)
        }
    }
}

我有与将程序集注入到RootViewController中完全相同的代码,该代码还检索情节提要并以与上述相同的方式实例化视图控制器。但这永远不会失败。

我无法确定为什么这会偶尔失败并且不一致的任何原因。但是我有一种感觉,可能是无法使用可选类型在Swift代码中正确初始化该程序集。可能是这样吗?还是可以建议我做些什么来使此代码有效?

编辑:

我已经从rootViewController和PaymentApproveViewController打印了TyphoonComponentFactory._registry。有趣的结果是:
  • 在RootViewController中,_registry包含我的ApplicationAssembly中所有台风定义的列表。也就是说,所有对象和情节提要板定义
  • 在PaymentApproveViewController中,_registry包含除我的五个情节提要板之外的所有对象。这就是TyphoonComponentFactory.componentForKey在找不到情节提要时抛出异常的原因。

  • 顺便说一句:程序集的地址在rootViewControllerPaymentApproveViewController中是不同的。因此,将注入两个不同的程序集。可以避免这种情况,还是预期的行为?

    最佳答案

    看来问题在于:

    $0.injectParameterWith(TyphoonBlockComponentFactory(assembly:self))
    

    这是仅使用当前定义中的定义实例化一个新程序集,并跳过任何协作程序集。您实际上想要:
    $0.injectParameterWith(self)
    

    在Objective-C中,可以将任何TyphoonAssembly强制转换为TyphoonComponentFactory(在运行时,程序集只是在任何情况下都冒充为程序集的TyphoonComponentFactory实例)。使用Swift的严格类型检查是不可能的,因此 Typhoon 3.0 TyphoonAssembly类符合TyphoonComponentFactory协议,因此,如果您需要此接口中的任何方法,则可以使用它们。例如:
    assembly.componentForType(SomeType.self)
    

    摘要
  • 在Swift中,我们只注入TyphoonAssembly而不是TyphoonComponentFactory
  • TyphoonAssembly符合TyphoonComponentFactory协议。
  • 关于ios - 台风:从装配体中提取 Storyboard 时发生异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29117143/

    10-09 05:22