2013-04-24 23 views
0

我有一個協議,我希望實現爲方法參數使用__weak引用。我定義我的協議爲:如何在協議實現的參數中強制實現__weak引用

@protocol TestProtocol 
-(void) op:(__weak NSObject*)x; 
@end 

然後,我創建一個實現:

-(void) op:(NSObject*)x 
{ 
} 

和X成爲一個有力的參考。如果我將__weak聲明移到協議實現中,那麼'x'是一個弱引用。由於協議的調用者已經保留了強有力的參考,我想確保實現不會創建另一個強有力的參考。

+0

你爲什麼要這麼做?調用者不需要關心該方法對變量的影響。該方法的實施可能,但應該自己聲明。 – hypercrypt 2013-04-24 19:16:56

+0

問題是,如果保留X並且op拋出,則x泄漏,但是如果X是弱引用,它不會泄漏。在我的情況下,調用者始終保持強有力的參考,不需要做任何操作,而且我避免了有例外的泄漏。 – 2013-04-24 19:19:56

+0

但是你爲什麼要扔x? – hypercrypt 2013-04-24 20:04:38

回答

3

我有點驚訝編譯器不抱怨聲明不匹配。而且,果然,它沒有。我提起雷達#13730581看看編譯器的人說什麼。

作爲@hypercrypt引用,在一般情況下,ARC不會保留或釋放方法的參數。少數情況下,犧牲性能與正確性之間的關係足以證明這種折衷。 (請注意,您會在未優化的案例中看到storeStrong,但在-Os案例Release build案例中沒有這樣的事情)。

這意味着你真的抵禦由於方法體內代碼的暗示而產生的強對象引用(並且根據註釋,當@throw「超過」時,強引用不會被拆除「 框架)。

您可以做的事情不多 - 如果您將x關閉,例如NSMutableArrayaddObject:方法,它將創建一個強有力的參考。

因此,在一般情況下,實際上並沒有一種方法可以防止強引用對象被創建爲變量使用的副作用。

具體到NSException清理,它不值得擔心。異常應該是致命的,拋出異常後應用程序的狀態是未定義的(除非可以確保沒有任何系統代碼與異常有任何關係,這是不可行的)。

// code tossed in main.m to play w/compiler behavior 

@protocol TestProtocol 
-(void) op:(__weak NSObject*)x; 
@end 

@interface DogBowl:NSObject <TestProtocol> 
@end 
@implementation DogBowl 
-(void) op:(NSObject*)x 
{ 
} 
@end