目前我在需要时直接对另一个对象进行硬编码,我希望能够通过init方法接受它(我假设?)。在下面的代码中,我在viewDidLoad方法中创建了一个新的HatService,出于可测试性/耦合的原因,我不想这样做。
- (void)viewDidLoad
{
[super viewDidLoad];
HatService* hatService = [[HatService alloc] init];
[hatService getHatById:self];
}
第一个问题 - 如何在Objective-c中完成? 第二个问题 - 我应该担心这个问题还是做到这一点?
更新
以下是我的开始,但我似乎从未在运行时遇到第一个init方法。我在界面中都声明了 - 我错过的任何其他东西都允许我覆盖这个init方法并注入服务依赖项?
注意 - 当我自己创建对象时,我可以手动点击这个但是当appDeleage完成工作时我没有看到它(如果app委托创建这个对象而不调用我的init方法?)
-(id)initWithHatService:(HatService *)service
{
if (self = [super init])
{
[self setService:service];
}
return self;
}
-(id)init
{
HatService* hatService = [[HatService alloc] init];
return [self initWithHatService:hatService];
}
答案 0 :(得分:6)
UIViewController
的指定初始值设定项为- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle
。如果您希望从nib文件中正确实例化视图控制器,则需要覆盖此方法,如果这是您正在尝试执行的操作。没有看到更多的代码,就无法分辨,但这种方法肯定会被称为某个地方。
其次,您需要重新编写-init
方法,如下所示:
- (id)init {
return [self initWithHatService:nil];
}
每个init方法都应调用指定的初始化程序。
最后,当您处理视图控制器时,人们通常不会在init方法中传递属性。实例化新控制器,然后将其传递给您喜欢的任何服务属性。
MyViewController *newContrlr = [[MyViewController alloc] initWithNibName:nil bundle:nil];
newContrlr.hatService = [[[HatService alloc] init] autorelease];
答案 1 :(得分:1)
如果您正在询问如何将对象传递给另一个对象的init方法,只需将您的init方法声明为接受一个或多个参数即可。即- (id) initWithHatService:(HatService *)serv;
init方法除了objective-c中的约定之外没有任何特殊之处。
无关:您的-getHatById:
方法很奇怪。那个内存管理语义是什么?在Cocoa程序中,get-prefixed方法非常罕见。
答案 2 :(得分:0)
在Objective-C中实现依赖注入设计模式非常容易。您可以通过创建定义单个协作者的“应用程序集”类来手动完成。
或者,您可以使用框架来提供帮助。我最近创建了一个名为Typhoon的DI容器:http://www.typhoonframework.org