ios - 使用Typhoon Assembly(plist方法)创建的AppDelegate创建了两次并且属性注入(inject)不起作用

标签 ios objective-c dependency-injection typhoon

我正在尝试使用 PList 集成方法引导 Typhoon,但我的 ApplicationDelegate 被创建了两次。第一次创建时,显然是由 Typhoon 创建的。那时,它使用特殊的初始化器 initWithAssembly: 并且 Typhoon 为其提供程序集。

第二次,也就是重要的时间,它是使用 init 创建的。它永远不会获得对程序集的引用。

为了以防万一,我还通过属性方法注入(inject)了程序集。不行。

这是代码:

组装

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

- (CTISApplicationDelegate *)appDelegate {
    return [TyphoonDefinition withClass:[CTISApplicationDelegate class]
                          configuration:^(TyphoonDefinition *definition) {
                              [definition useInitializer:@selector(initWithAssembly:) parameters:^(TyphoonMethod *initializer) {
                                  [initializer injectParameterWith:@(3)];
                              }];

                              definition.scope = TyphoonScopeSingleton;
                          }];
}

AppDelegate

@property (nonatomic, strong, readwrite) ApplicationAssembly *assembly;

@property (nonatomic, strong, readwrite) UIWindow *window;

- (instancetype)initWithAssembly:(ApplicationAssembly *)assembly;

...

// This gets called once, the first time, and assembly is NOT nil.
- (instancetype)initWithAssembly:(ApplicationAssembly *)assembly {
    self = [super init];

    if (self) {
        self.assembly = assembly;
    }

    return self;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];

// This gets ca

填充一次(在第二次初始化之后)并且 self.assemble 为零。

AcceptDisclaimerAppInfoModule *disclaimer = [[self.assembly applicationInformationModuleAssembly] acceptDisclaimerModule];

[disclaimer launchModuleFromWindow:self.window];

[self.window makeKeyAndVisible];
return YES;

}

最佳答案

在网上查看并疯狂地思考这个问题之后,我得出了一些结论。

问题的根源在于 Typhoon和我的main.m入口点不以任何形式同步。所以,main.m来电 UIApplicationMain()其中一个参数是一个字符串,指定 id<UIApplicationDelegate> 的类型你要。我从未见过任何偏离这种模式的情况,所以我不愿意改变它。

因此,假设 id<UIApplicationDelegate>不会通过 Typhoon 构建以一种“内置”到框架中的方式。虽然您可以执行以下操作之一,但我不推荐任何操作:它们似乎都是错误的。

  • 实例化您的根实例 TyphoonAssembly直接来自您的应用委托(delegate)
  • 创建一个单例 IContainer可以拥抱TyphoonAssembly的物体启动时创建的实例
  • 以邪恶的方式使用与关联对象相关的类别

问题是......在某些时候,如果你没有做对,你将需要做其中一件邪恶的事情,无论如何。

原因是... Typhoon显然是为了在“对象图”的上下文中工作而设计的,所以整个TyphoonAssembly任何连接的集合都可以被视为图网。一旦您进入网络,就可以了 - 您可以从那里获取它。您只需进入...

因此,我决定执行以下操作:

  1. 为我称为 IContainer 的相关对象的每个“对象图”创建接口(interface),即使它们跨越多个程序集或者小于程序集。这断开了 Typhoon 的想法来自IContainer并且可以在没有 Typhoon 的情况下进行调试通过替换模拟 IContainer就位。
  2. 仅使用构造函数注入(inject),除非有一种非常值得注意的情况 - 我刚才提到的应用程序委托(delegate)。在那里,使用属性注入(inject)仅注入(inject)一个属性 - IContainer有问题。
  3. 每当您使用属性注入(inject)时,您不妨只注入(inject)一个属性,即 IContainer ,因为您已经破坏了封装,您不妨让自己变得容易一些。
  4. 实现一些有趣的事情来向自己证明 Typhoon的默认范围按照您想象的方式工作。每当我检测到对同一对象图中的任何构造函数的多次调用时,我都会实现一些“警报”。
  5. 使用id<nonatomic, weak>对于委托(delegate)类型,不是 id<nonatomic, assign>正如我去年所做的那样。关于路上的事Typhoon幕后工作必须不断地释放代表。
  6. 使用 PList 注入(inject)和程序集组合。一个例子:

在 Info.plist 中,添加一个名为 TyphoonInitialAssemblies 的键与 Array type 和values 是程序集的类名。但是...

不要忘记做另一半,即确保您有一个像RootAssembly这样的“根”程序集。然后是一些ModuleAssemblyRootAssembly 存储的:

@protocol IAppLaunchContainer

- (UIWindow *)launchWindow;
- (UIViewController *)launchRootViewController;
- (UIImageView *)launchImageView;

@end

@protocol IDefaultUIComponentsContainer

- (UIView *)uiDefaultView;
- (UILabel *)uiDefaultLabelWithName:(NSString *)name;
- (UIButton *)uiDefaultButtonWithTitle:(NSString *)title;

@end

@interface RootAssembly : TyphoonAssembly<IAppLaunchContainer, IDefaultUIComponentsContainer>

@property (nonatomic, strong) SubAssemblyA *thisModuleAssembly;
@property (nonatomic, strong) SubAssemblyB *thatModuleAssembly;

@end

在这种情况下,您的 Info.plist 将具有:

  1. TyphoonInitialAssemblies (Array)
    • SubAssemblyA
    • SubAssemblyB

关于ios - 使用Typhoon Assembly(plist方法)创建的AppDelegate创建了两次并且属性注入(inject)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30868675/

相关文章:

ios - UITableView:上一节页脚中的元素数

ios - 本地通知覆盖iOS 9中的远程通知(可行通知)设置?

iphone - 本地通知行为

iphone - Objective-c UIImage 存储在 MSMutableArray 替代方案中,潜在的内存泄漏?

ios - tablecell 背景仅显示自定义单元格,但显示自定义单元格使其无法选择

iphone - 用于检测电话号码和超链接的 UITextView 设置

java - MentaContainer 上的自动布线不起作用?

c# - 开放泛型的 DI 绑定(bind)是一种反模式吗?

ios - Assets 目录中设备特定图像集中的设备

java - 使用构造函数注入(inject)时如何避免循环依赖