2013-04-16 38 views
0

我想將一個自定義對象分配給一個實例變量。爲什麼在使用setter將自定義對象分配給實例變量時使用autorelease?

下面是代碼:
- MyController.h/.M

#import "CustomData.h" 
@interface MyViewController : NSViewController 
@property (retain) CustomData* theData; 

- (void)aRandomMethod; 

@end 

@implementation MyViewController 
@synthetize theData; 

- (void)aRandomMethod { 

    NSData* rawData = [someOtherObject someOtherMethod]; 

    // option 1 
    self.theData = [[CustomData alloc] initWithData:rawData]; 

    // option 2 
    CustomData* _theData = [[Custom alloc] initWithData:rawData]; 

    // option 3 
    self.theData = [[[CustomData alloc] initWithData:rawData] autorelease]; 

    // option 4 
    theData = [[CustomData alloc] initWithData:rawData]; 

    // ... later code calls some methods on theData or _theData, not useful here. 
} 
@end 

當運行在Xcode的分析功能,它告訴我,有一個「後未引用泄漏的對象......」對於選項1和2,但不適用於3和4.在使用setter時,似乎需要autorelease自定義對象。我知道autorelease需要在返回方法中我們擁有的對象時使用。

你能解釋每個選項爲什麼是錯的或正確的?謝謝。

+0

您錯過了在每個選項行打開大括號。 –

回答

5

選項1是錯誤的,因爲你的alloc'd是該方法中的對象,所以該方法現在擁有該對象,因此需要release它。當你將它分配給一個屬性時,它會被retain取代,當它完成後,它會被release取代。

由於相同的原因,選項2是錯誤的。您將屬性部分取出,但由於您創建的對象爲alloc,因此您需要負責在該方法中調用release

選項3是正確的,因爲在將它提供給屬性之前它已經autorelease d,所以方法不再擁有它。請注意,如果您在這裏使用release它會中斷,因爲它會在release它之前獲得一個機會retain它。

選項4可能是正確的;我假設它將它分配給伊娃。如果您以後在dealloc方法中手動釋放ivar,這纔是正確的。儘管通過屬性通常會更好。否則,您將冒着分配另一個值的風險,並忘記release現有的值。

1

選項1和選項2最值得注意的是有一個分配,因此需要是相應的版本。

選項1本質上是「隱藏」的,因爲編譯器自動爲您創建setter和getters。你沒有看到的是,當使用點符號時,你正在經歷setter,它隱式地包含了一個保留調用。因此,您正在分配對象並保留,因此保留計數爲2.

因此,爲了確保將來能夠正確釋放它,您必須將其指定爲添加到自動釋放池以供系統稍後清理。這將使保留計數爲1,然後在您的dealloc方法中,您可以安全地釋放該屬性。

相關問題