2011-01-09 62 views
3

目前我在需要的時候直接對另一個對象進行硬編碼,我希望能夠通過初始化方法(我假設?)進行這項工作。在下面的代碼中,我在viewDidLoad方法中創建了一個新的HatService,爲了可測試性/耦合的原因,我不希望這樣做。你可以在objective-c中完成某種形式的依賴注入嗎?

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    HatService* hatService = [[HatService alloc] init]; 
    [hatService getHatById:self]; 
} 

第一個問題 - 這應該怎麼做在objective-c? 第二個問題 - 我應該擔心這個問題還是一直這麼做?

更新

這裏是我開始用,但我似乎從來沒有在運行過程中碰到的第一個init方法。我都在界面中聲明瞭 - 我錯過的其他任何東西都會允許我重寫這個init方法並注入服務依賴項?

注 - (?如何應用程序的委託創建這個對象沒有打電話給我的init方法),當我創建對象,我可以手動打這個自己,但在appDeleage做的工作時,我沒有看到它打這個

-(id)initWithHatService:(HatService *)service 
{ 
    if (self = [super init]) 
    { 
    [self setService:service]; 
    } 
    return self; 
} 

-(id)init 
{ 
    HatService* hatService = [[HatService alloc] init]; 
    return [self initWithHatService:hatService]; 
} 

回答

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

如果您要問如何將對象傳遞給另一個對象的init方法,只需將init方法聲明爲接受一個或多個參數即可。即- (id) initWithHatService:(HatService *)serv;除了Objective-C中的約定以外,init方法不是特殊的。

無關:您的-getHatById:方法很好奇。那是什麼內存管理語義?獲取前綴的方法在Cocoa程序中很少見。

+0

這是我的第一個想法 - 但是如果我想要提供默認實現,我可以做另一個只調用一個w/args的init(類似於java中的可憐人DI/c#) - 關於你無關的說明..應該這個autorelease或什麼是最好的選擇?仍然是新的內存管理的東西,並有很多返工在我的名單上(任何幫助將是偉大的!) – 2011-01-09 23:55:52

0

在Objective-C中實現依賴注入設計模式非常容易。您可以通過創建定義單個協作者的「應用程序集」類來手動完成。

或者,您可以使用框架來協助。我最近創建了一個名爲Typhoon的DI容器:http://www.typhoonframework.org