台风与单身AppDelegate

时间:2014-11-05 15:55:50

标签: ios objective-c iphone dependency-injection typhoon

我正在使用台风与Plist整合'

我在程序集中定义了AppDelegate如下:

- (AppDelegate *)appDelegate {
    return [TyphoonDefinition withClass:[AppDelegate class] configuration:^(TyphoonDefinition *definition) {
        [definition injectProperty:@selector(window)];
        definition.scope = TyphoonScopeSingleton;
    }];
}

window内,我有rootViewController delegateAppDelegate实施。

- (RootViewController *)rootViewController {
    return [TyphoonDefinition withClass:[RootViewController class] configuration:^(TyphoonDefinition *definition) {
        [definition injectProperty:@selector(delegate)]; 
    }];
}

问题是delegate设置为另一个AppDeleaate实例。我在AppDelegate init内设置了一个断点,实际上它被调用了两次。

我知道解决方案是在运行时在delegate内手动设置AppDelegate,但我希望这可以由台风来处理。

注意:我没有尝试过,但故事板创建的视图控制器可能会发生同样的事情。

2 个答案:

答案 0 :(得分:3)

好问题。

Typhoon没有注入你的初始AppDelegate,因为它是在台风之外创建的。台风有一些对象池,它们被用来注入另一个物体,如果Typhoon没有在池中对象,它将使用指定的初始化器创建(如果作用域是单例,则保留)。

从故事板创建的ViewControllers将被正确注入,因为它们是在Typhoon中创建的。

要解决您的特定问题,请尝试AppDelegate的此定义:

- (AppDelegate *)appDelegate {
    return [TyphoonDefinition withClass:[AppDelegate class] configuration:^(TyphoonDefinition *definition) {
        [definition setFactory:[self sharedApplication]];
        [definition useInitializer:@selector(delegate)];
        [definition injectProperty:@selector(window)];
        definition.scope = TyphoonScopeSingleton;
    }];
}

- (UIApplication *)sharedApplication {
    return [TyphoonDefinition withClass:[UIApplication class] configuration:^(TyphoonDefinition *definition) {
        [definition useInitializer:@selector(sharedApplication)];
    }];
}

然后在解析appDelegate定义期间,Typhoon将调用[[UIApplication sharedApplication] delegate]方法并在Typhoon中注册返回的实例。

通过这种方式,AppDelegate将只创建一次(通过UIApplication)..但是注射将被应用两次(一次duting启动,第二次解析appDelegate定义时第一次)

<强>更新

在台风内部确定了AppDelegate个案。您的原始代码现在可以使用(使用head版本或将来的版本)。

答案 1 :(得分:0)

这似乎在8.4中再次破裂。

在进行Typhoon plist集成时,最终会有2个AppDelegates。 UIApplication创建的那个和Typhoon管理的那个。

我从当前Typhoon docs创建appDelegate的方式切换到了:

public dynamic func appDelegate() -> AnyObject {
return TyphoonDefinition.withClass(AppDelegate.self) {
  (definition) in

  // load up any environment variables/injections
  definition.injectProperty("assembly", with: self)
  definition.injectProperty("window", with: UIWindow(frame: UIScreen.mainScreen().bounds))
  definition.scope = TyphoonScope.LazySingleton
}  

Alekseys的答案来做IAW。

这解决了2x AppDelegate问题,但这会留下鸡蛋问题;特别是在通过plist创建Typhoon程序集之前,由UIApplication 创建了AppDelegate。因此,如果您的视图控制器由Typhoon管理,而不是通过故事板管理,那么在appDelegate的didFinishLaunchingWithOptions设置阶段它们将不存在。

为了解决这个问题,我最终让Typhoon Assembly成为一个正常的单例,并删除了plist集成。

我希望这可以帮助人们解决同样的问题。