我正在尝试使用 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
任何连接的集合都可以被视为图网。一旦您进入网络,就可以了 - 您可以从那里获取它。您只需进入...
因此,我决定执行以下操作:
- 为我称为
IContainer
的相关对象的每个“对象图”创建接口(interface),即使它们跨越多个程序集或者小于程序集。这断开了Typhoon
的想法来自IContainer
并且可以在没有Typhoon
的情况下进行调试通过替换模拟IContainer
就位。 - 仅使用构造函数注入(inject),除非有一种非常值得注意的情况 - 我刚才提到的应用程序委托(delegate)。在那里,使用属性注入(inject)仅注入(inject)一个属性 -
IContainer
有问题。 - 每当您使用属性注入(inject)时,您不妨只注入(inject)一个属性,即
IContainer
,因为您已经破坏了封装,您不妨让自己变得容易一些。 - 实现一些有趣的事情来向自己证明
Typhoon
的默认范围按照您想象的方式工作。每当我检测到对同一对象图中的任何构造函数的多次调用时,我都会实现一些“警报”。 - 使用
id<nonatomic, weak>
对于委托(delegate)类型,不是id<nonatomic, assign>
正如我去年所做的那样。关于路上的事Typhoon
幕后工作必须不断地释放代表。 - 使用 PList 注入(inject)和程序集组合。一个例子:
在 Info.plist 中,添加一个名为 TyphoonInitialAssemblies
的键与 Array
type 和values 是程序集的类名。但是...
不要忘记做另一半,即确保您有一个像RootAssembly
这样的“根”程序集。然后是一些ModuleAssembly
由 RootAssembly
存储的:
@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 将具有:
-
TyphoonInitialAssemblies
(Array
)-
SubAssemblyA
-
SubAssemblyB
-
关于ios - 使用Typhoon Assembly(plist方法)创建的AppDelegate创建了两次并且属性注入(inject)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30868675/