2015-08-19 41 views
0

我有一個對象被設置爲另一個對象的代理,其delegate屬性很弱。有沒有辦法將弱引用變成強引用?

- (YYService *)service 
{ 
    XXHandler *handler = [[XXHandler alloc] init]; 

    // YYService's "delegate" property is weak 
    return [[YYService alloc] initWithDelegate:handler]; 

    // The XXHandler is deallocated because there are no strong references to it 
} 

由於沒有別的引用它最終得到釋放的委託,但我想它的生活,只要父對象確實猶如父母有強烈參考其委託。有沒有簡單的方法來實現這一點?

+0

爲什麼你不能讓代表成爲強有力的參考? – dudeman

+0

顯示一些相關的代碼來爲您的問題提供上下文。 – rmaddy

+0

@MikeAtNobel,我沒有提到它的問題,但與委託的類是從第三方庫 – ide

回答

0

容易爲什麼要「解決」這個問題是子類YYService,給子類一個額外的強大屬性,並在-initWithDelegate:設置一個。

但是這個「解決方案」會加深設計中的問題,而不是解決問題。

讓我們來看看,爲什麼代表們常常會舉辦弱:

委派類有一個一般的 - 或沒有 - 行爲,可能不適合在這個類的用戶的情況下,我。即如果有事情發生。 (一個操作完成,發生錯誤,$ whatever)所以委託類給你提供了自定義行爲的機會,包括運行自定義代碼。委託與子類化競爭,但與子類化不同的是每個實例(而不是每個類)和運行時(而不是編譯時)。

因爲它在每個實例的基礎上工作,創建委託的實例通常強烈地持有委託實例。此代碼知道應當向委託實例的定製:

-(void)createDelegate 
{ 
    self.delegating = [Delegating new]; // I create and hold the instance strongly 
    delegating.delegate = self;   // I customize it 
} 

然後委託實例不能牢固地保持委託,因爲這將是一個保留週期。

在您的代碼段不起作用,因爲-service返回新創建的委託實例。甚至可以返回兩個實例,我不喜歡它,因爲創建委託對象和安裝委託將是一個兩步操作,即使它在語義上也是一步一步的操作。所以,如果您還沒有self作爲委託你,你應該做的整個安裝過程中的一個方法:

-(void)installService 
{ 
    self.handler = [[XXHandler alloc] init]; // Hold the handler strongly 
    self.service = [[YYService alloc] initWithDelegate:handler]; 
} 

如果你不知道作爲代表具體的實例對象,把它作爲參數:

-(void)installServiceWithDelegate:(id)delegate 
{ 
    self.delegate = delegate; 
    self.service = [[YYService alloc] initWithDelegate:delegate]; 
} 

… 

[self installServiceWithDelegate:[YourConcreteClass new]]; 

但是你不應該嘗試to turn things upside down or inside out

相關問題