2011-08-13 62 views
1

我有一個的UIScrollViewUIViewController中在我.h文件中定義爲這樣:爲什麼我的財產是潛在的泄漏,我該如何解決?

#import <UIKit/UIKit.h> 

@interface TestViewController : UIViewController <UIScrollViewDelegate> 

@property (nonatomic, retain) UIScrollView * imageScrollView; 

@end 
在我的.m文件

然後,我有以下幾點:

@synthesize imageScrollView = _imageScrollView; 

,我讀了這會自動創建我通常在.h文件中輸入的_imageScrollView? (UIScrollView * _imageScrollView)

我喜歡它,因爲它從我的.h文件中刪除了重複的代碼。現在在我的的loadView我做休息:

self.imageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0 - 20.0 - 49.0)]; 
[_imageScrollView setDelegate:self]; 
[_imageScrollView setPagingEnabled:YES]; 
[_imageScrollView setBounces:NO]; 
[_imageScrollView setShowsHorizontalScrollIndicator:NO]; 
[_imageScrollView setShowsVerticalScrollIndicator:NO]; 
[_imageScrollView setContentSize:CGSizeMake(320.0 * 3.0, 480.0 - 20.0 - 49.0)]; 

而在的dealloc釋放和零:

- (void)dealloc 
{ 
[_imageScrollView release], _imageScrollView = nil; 

[super dealloc]; 
} 

現在構建的Xcode告訴我這個後:

Potential leak of an object allocated on line #linenumber 

當我改變這個時,這將消失:

self.imageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0 - 20.0 - 49.0)]; 

這樣:

self.imageScrollView = [[[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0 - 20.0 - 49.0)] autorelease]; 

爲什麼我需要的時候,我在dealloc中釋放自動釋放呢?我究竟做錯了什麼?

此內存警告只發生在Xcode在我的iMac電腦安裝,而不是我的MacBook雪豹獅子...

回答

2

這是因爲你的imageScrollView屬性被宣佈爲retain屬性。這意味着當您設置它時,訪問器(由@synthesize生成)將自動保留該值。如果你不想要這種行爲,你應該聲明你的財產是assign。 (但你想在這種情況下,這種行爲)。

無論如何,這樣你的對象保留兩次,一次在你的代碼,一旦被存取,所以它永遠不會釋放。永遠記住,self.imageScrollView =就像[self setImageScrollView:],那東西發生在那裏!

(也是最後一次,內存警告,因爲舊的Xcode沒有發現錯誤,不是因爲錯誤是不存在只發生在獅子。)

+0

啊是的,現在對我來說很有意義..(看起來我不能在這裏輸入)我怎樣才能避免autorelease?還是在這種情況下唯一的(也是最好的)選擇?通常當我創建一個臨時對象時,我會在完成它之後立即釋放它。如果可能有辦法在任何時候只保留一次,用這樣的東西填充autorelease池是否不好? –

+1

Autorelease可能是您最好的選擇。確實,autorelease池可能會很慢,但前提是代碼被稱爲數千次。如果你在一個緊密的循環中分配了很多東西,那麼你可能需要創建一個臨時變量來指向你的新視圖,將imageScrollView設置爲它,然後在你的臨時變量上調用release。這樣你可以在釋放之前設置,所以你不需要autorelease。 (但是,只要你注意到它很慢)。 – andyvn22

+0

你的意思是這樣的:UIScrollView * imageScrollView = [[UIScrollView alloc] init]; [self setImageScrollView:imageScrollView]; [imageScrollView發佈];該應用程序不是很慢(或者我至少沒有注意到它),但對於任何未來的項目,我只是想明白這一點(但我認爲現在是,現在再次感謝您!) –

2

你與retain選項定義你的財產。這意味着,當您將一個對象分配給該屬性時,該對象將被保留 - 您「擁有」對象的所有權。在這種情況下,這很好,因爲您希望UIScrollView在您需要時可以繼續使用。我應該注意到,您也擁有從名稱以allocnewcopymutableCopy開始的方法返回的任何對象。

所以,看你的代碼,你可以看到你自己,你有alloc創建UIScrollView,但你要求的所有權再次當你把它存儲在財產。這意味着內存永遠不會被回收。通過調用autorelease,您在將其分配給屬性之前放棄對象的所有權,這意味着調用releasedealloc將按預期工作。

我建議你閱讀Objective-C編程語言文檔的Memory Management Programming GuideDeclared Properties部分。

+0

謝謝你回答:)可悲的是,給兩個人正確的答案是不可能的!我會再讀一遍:) –

+0

+1:很好的參考資料! – andyvn22