2011-10-10 45 views
4

出於好奇/興奮我一直在閱讀關於ARC的任何信息,但我有一個問題,我似乎無法找到答案。不確定人們是否可以通過NDAs或其他方式來回答這個問題,但我仍然會問。 (這裏有很多信息.......)ARC和自定義deallocs

ARC公佈的一件事是,您不需要再編寫dealloc方法。涼。但這是真的嗎?

如果我有一個NSNetService什麼的,通常在我的dealloc我會寫

- (void)dealloc 
{ 
    [netService_ setDelegate:nil]; 
    [netService_ stop]; 
    [netService_ release]; 

    [super dealloc]; 
} 

不ARC現在照顧的是什麼?還是不夠聰明知道這樣的東西?如果它沒有足夠的智能來知道這些東西(意思是在某些情況下我仍然需要編寫自定義的dealloc),我是否必須發佈所有的ivars?或者只是那些不會是簡單的版本?

- (void)dealloc 
{ 
    [netService_ setDelegate:nil]; // if these 3 lines are necessary... 
    [netService_ stop]; 
    [netService_ release]; 

    [myString_ release]; // would this one still be? or would ARC know to automagically add this 
    [super dealloc]; // seems this is forbidden in ARC 
} 

我想我的問題真的歸結爲這個:ARC說你不必在大多數情況下寫deallocs了;那麼你需要什麼情況?

+0

每當你寫自己的dealloc時,不要忘記調用[super dealloc](如你在示例代碼中所示) – Danra

+0

謝謝。我會編輯。我離開了它,因爲我認爲在啓用ARC時這是錯誤的。 – user988375

+2

@Danra,你不要在ARC下調用'[super dealloc]'。 – Jim

回答

4

據我所知,你應該將ARC看作是編譯器內置的靜態分析器,在需要時綜合保留和釋放調用(這也是ARC代碼向後兼容設備的原因運行iOS4)。

所以你的樣品中沒有辦法netService_會自動停止。在這種情況下,你需要編寫你自己的dealloc。

委託問題很有趣,在iOS5中它將是一個弱屬性,所以它可能被設置爲零dealloc ...不知道,但它很有趣!

另一種情況下,您需要處理的不是客觀的c對象,例如對於Core Foundation對象,您需要自己編寫CFRetain s和CFRelease s。

+0

啊,是的,我記得現在閱讀關於那些調零弱的屬性......你說得對,理論上應該處理它自己。我想你不能依賴那裏的每一個班級作爲弱財產委託嗎? – user988375

+0

每個寫得好的類都應該有它的代表作爲weak/assign屬性。另請參閱此:http://stackoverflow.com/questions/7246513/zeroing-weak-references-in-arc – Danra

2

我認爲如果你需要做任何事情來清理對象,其他比釋放它,是一個自定義dealloc方法的公平遊戲。

因此,在你自己的例子有netService_,以setDelegate:stop的通話將合理調用,但會是無需調用release因爲ARC需要的照顧。

+0

如果真是這樣,那真是太棒了。看起來很合理。 – user988375

+0

'setDelegate:'調用應該是不必要的,假設它被正確設置爲一個歸零弱引用。 @ user988375 –

+0

@JoshCaswell如果代表(或另一個對象)是一個「強」引用,該怎麼辦?那麼你需要在dealloc中將它設置爲'nil'? –

0

很明顯,ARC不會知道你的[netService_ stop];系列。你必須自己加入,因爲它是非標準的,不需要retain/release

dealloc運行後立刻ARC將釋放所有strongweak屬性(和__strong__weak高德)。

這裏的一些測試代碼,只是爲了看看會發生什麼:

@interface TestClass : NSObject 

@property (nonatomic, strong) TestClass *anotherTestObject; 

@end 


@implementation TestClass 
@synthesize anotherTestObject; 

- (void)dealloc { 
    NSLog(@"I am deallocing %d", self.hash); 
} 

@end 

而且我的測試:

TestClass *thing1 = [[TestClass alloc] init]; 
NSLog(@"thing 1 %d", thing1.hash); 

thing1.anotherTestObject = [[TestClass alloc] init]; 
NSLog(@"thing 2 %d", thing1.anotherTestObject.hash); 

這將打印出這樣的事情

thing 1 1450176 
thing 2 1459984 
I am deallocing 1450176 
I am deallocing 1459984 

由於只有一個的對象在測試代碼的末尾獲得自動發佈(thing1),則可以立即y告訴thing2正在被別人釋放(因爲它屬於strong屬性)。但是,如果您覆蓋setAnotherTestObject,則會發現ARC是而不是將其設置爲nil,而是直接將其釋放。你不能覆蓋ARC release,否則我也能證明這一點;)

如果我調整了代碼,並使用weak代替strong,同樣的問題仍然存在,但輸出是不同的,因爲測試情況下,不持有到無論如何都是弱點。