我正在尝试使用PList集成方法引导Typhoon
,但是我的ApplicationDelegate
被创建了两次。第一次创建它时,显然是由Typhoon
创建的。那时,它使用特殊的初始化程序initWithAssembly:
,并且Typhoon
将其提供给程序集。
第二次是重要的时间,它是使用init
创建的。它从不引用程序集。
以防万一,我还通过property方法注入了assembly
。不行
这是代码:
大会
- (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.assembly为零。
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
的实例IContainer
对象,该对象可以拥抱在启动TyphoonAssembly
实例问题是……在某个时候,无论您做得如何,您都将需要做这些邪恶的事情之一。
原因是...
Typhoon
显然是为在“对象图”的上下文中工作而设计的,因此整个TyphoonAssembly
和任何连接的程序集都可以视为图的网。上网之后,您就可以了-您可以从那里接单。您只需要进入...因此,我决定执行以下操作:
IContainer
的相关对象的每个“对象图”创建接口,即使它们跨越多个程序集或小于一个程序集。这将Typhoon
的思想与IContainer
断开了联系,并且可以通过在适当的位置替换一个模拟的Typhoon
来进行调试而不使用IContainer
。 IContainer
。 IContainer
,因为您已经破坏了封装并且还可以使自己变得容易。 Typhoon
的默认范围可以按照您认为的方式起作用。每当我在同一对象图中检测到对任何构造函数的多次调用时,便实现了一些“警报”。 id<nonatomic, weak>
用于代表类型,而不是像过去一年那样使用id<nonatomic, assign>
。关于Typhoon
的幕后工作方式,必须使它不断地被委托释放。 在您的Info.plist中,添加一个名为
TyphoonInitialAssemblies
的键,其键类型为Array
,其值是程序集的类名。但...别忘了做另一半,这是确保您有一个像
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