2010-07-27 31 views
1

我注意到我寫的程序的內存使用量隨着時間的推移而不斷增加。 XCode的儀器顯示沒有內存泄漏,但你可以看到隨着時間的推移棧堆增長..IBOutlet,是否使用會員屬性?內存泄漏?

經過調查,大量的內存使用來自IBOutlet UI對象。界面是用Interface Builder構建的。

典型用法是這樣的:

頭:

@interface HelpViewController : UIViewController <UIWebViewDelegate> { 
    IBOutlet UIWebView *webView; 
    IBOutlet UIBarItem *backButton; 
    IBOutlet UIBarItem *forwardButton; 
    NSString *URL; 
    IBOutlet UIActivityIndicatorView *spin; 
} 

@property (nonatomic, retain) NSString *URL; 

而對於用法:

- (void)webViewDidStartLoad:(UIWebView *)mwebView { 
    backButton.enabled = (webView.canGoBack); 
    forwardButton.enabled = (webView.canGoForward); 
    [spin startAnimating]; 
} 

- (void)webViewDidFinishLoad:(UIWebView *)webView { 
    backButton.enabled = (webView.canGoBack); 
    forwardButton.enabled = (webView.canGoForward); 
    [spin stopAnimating]; 
} 

望着堆棧,你會發現UIActivityIndi​​catorView *旋轉對象ISN沒有妥善釋放,其內存佔用將繼續增長。

但是,如果我的代碼更改爲: 頭:

@interface HelpViewController : UIViewController <UIWebViewDelegate> { 
    IBOutlet UIWebView *webView; 
    IBOutlet UIBarItem *backButton; 
    IBOutlet UIBarItem *forwardButton; 
    NSString *URL; 
    UIActivityIndicatorView *spin; 
} 

@property (nonatomic, retain) NSString *URL; 
@property (nonatomic, assign) IBOutlet UIActivityIndicatorView *spin; 

而在代碼中,我做的事:

synthesize spin; 

- (void)webViewDidStartLoad:(UIWebView *)mwebView { 
    backButton.enabled = (webView.canGoBack); 
    forwardButton.enabled = (webView.canGoForward); 
    [self.spin startAnimating]; 
} 

- (void)webViewDidFinishLoad:(UIWebView *)webView { 
    backButton.enabled = (webView.canGoBack); 
    forwardButton.enabled = (webView.canGoForward); 
    [self.spin stopAnimating]; 
} 

僅此而已,沒有別的,然後堆棧不在任何地方增長..和UIActivityIndi​​catorView對象不會留下任何東西

我不明白爲什麼它會在這裏有一個分配屬性的區別o不,它只是沒有意義!除非我大量誤解了發生的事情。

將受到歡迎任何解釋..

感謝

回答

3

你需要釋放的dealloc方法中的對象:



-(void)dealloc { 
    [webView release]; 
    [backButton release]; 
    [forwardButton release]; 
    [URL release]; 
    [spin release]; 
    [super dealloc]; 
} 

爲什麼這個問題不會在你的第二個occour原因版本是,你設置屬性分配的屬性,通常你應該使用保留爲「對象屬性」分配通常用於像int,float,bool等基本數據類型...

編輯:

與保留和分配,據我所知的行爲是下面的部分: 如果屬性與分配做,然後設置


self.thatVariable = something; 

將是一樣的:


thatVariable = something; 

,如果您使用保留這將是一樣的:


[thatVariable release]; 
thatVariable = [something retain]; 

所以如果你使用賦值變量來保存指向對象的指針,你不能確定,你的對象不會被釋放到其他地方,這會導致訪問不良。

Afaik使用對象賦值的唯一理由是得到一個弱引用。如果你必須反對哪一個會保留對方,那麼它們都不會被釋放。所以這是你將使用分配給對象的地方。 (通常在委託模式中,對象會保留它的委託,並且委託將保留該對象,在這種情況下委託經常被分配)

+0

我認爲建議使用'self.webView = nil; 「而不是你的dealloc或viewDidUnload方法中的'[webView release]'。無論您在@property語句中使用release還是assign,這都做對了。 (只是不要忘記自己的部分,這將是非常糟糕的。) – 2010-07-27 15:44:07

+1

在dealloc中,您應該始終使用[webView發佈]而不是self.webView = nil,以避免清除觸發任何KVC觀察者或任何其他方影響。 – 2010-07-27 17:38:58

+0

對不起,但這並不能解釋爲什麼分配屬性和沒有屬性之間會有所不同。 這兩種情況都會觸發增加的內存使用。 順便說一句,如果使用assign屬性,在dealloc中執行釋放將觸發分段錯誤。如果你在dealloc中發佈一個版本,你需要使用retain屬性 – jyavenard 2010-07-27 19:30:54