2

我正在使用带有“Plist 集成”的台风

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

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

在里面window,我有一个rootViewControllerdelegate它实现的AppDelegate

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

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

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

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

4

2 回答 2

4

好问题。

Typhoon 没有注入您的初始 AppDelegate,因为它是在 Typhoon 之外创建的。Typhoon 有内部对象池,它们用于注入另一个对象,如果 Typhoon 在池中没有对象,它将使用指定的初始化程序创建(如果范围是单例则保留)。

从情节提要创建的 ViewController 将被正确注入,因为它们是在 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)。但注入将应用两次(一次在启动时,第二次在第一次解析 appDelegate 定义时)

更新

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

于 2014-11-06T12:06:15.210 回答
0

这似乎在 8.4 中再次被打破。

在进行 Typhoon plist 集成时,您最终会得到 2 个 AppDelegates。一个由 UIApplication 创建,一个由 Typhoon 管理。

我从当前的 Typhoon 文档中切换到创建 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 问题,但留下了先有鸡还是先有蛋的问题;特别是 AppDelegate 是由 UIApplication在通过 plist 创建 Typhoon Assembly之前创建的。因此,如果您的视图控制器由 Typhoon 管理,而不是通过情节提要,它们将不会在您的 appDelegate 的 didFinishLaunchingWithOptions 设置阶段存在。

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

我希望这可以帮助人们在同样的问题上挣扎。

于 2015-08-28T15:53:37.767 回答