2010-07-27 6 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]; 
} 

힙 스택을 보면, 당신은 것을 알게 UIActivityIndicatorView * 스핀 객체 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]; 
} 

아무것도, 아무것도 후 힙 스택은하지하지 않습니다 어디서나 커지면 .. UIActivityIndicatorView 객체가 뒤에 물건을 남기지 않는다.

왜 내가 여기에 속성을 할당하는 데 차이가 있는지 알 수 없다. r 아닙니다, 그것은 단지 이해가 안됩니다! 내가 무슨 일이 일어나고 있는지 오해하지 않는다면.

환영 할 것입니다 모든 설명은 ..

감사

당신은의 dealloc 메서드에서 개체를 해제 할 필요가

답변

3

:



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

문제가 두 번째에 occour하지 않는 이유 버전은 속성 할당을 사용하여 속성을 설정하는 것이고 일반적으로 "객체 속성"에 대해 retain을 사용해야합니다. int, float, bool 등의 기본 데이터 유형에 일반적으로 사용됩니다.

편집 :

: 속성이 다음과 같은 것

self.thatVariable = something; 

설정, 할당로 만든 경우 : 동작 AFAIK 다음은, 유지 및 지정에 부분에


thatVariable = something; 

이 유지 사용하는 경우는 같은 것이다 :


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

그래서 확실하지 않은 객체에 대한 포인터를 저장하는 변수에 assign을 사용하면 객체가 다른 곳에 할당되지 않아 액세스가 잘못 될 수 있습니다.

Afaik는 객체와 함께 assign을 사용하는 유일한 이유는 약한 참조를 얻는 것입니다.둘 다 서로를 유지할 것이라는 것을 객관적으로 밝혀야 만한다면, 어느 누구도 그것을 풀 수 없을 것입니다. 그래서 당신이 객체를 위해 할당을 사용할 곳을 가리 킵니다. (대개 대리자 패턴에서 객체는 객체를 보유 할 것이고 대리자는 객체를 유지할 것입니다.이 경우에는 대리자가 종종 할당됩니다)

+0

'self.webView = nil; ' 대신 dealloc 또는 viewDidUnload 메소드에서 '[webView release]'를 사용하십시오. 이것은 @property 문에서 release 나 assign을 사용하든 옳은 일을합니다. (자기 부분을 잊지 마라. 매우 나쁠 것이다.) –

+1

dealloc에서는 KVC 관찰자를 트리거하거나 다른 쪽을 갖는 것을 피하기 위해 self.webView = nil 대신 항상 [webView release]를 사용해야한다. 효과. –

+0

죄송합니다. 그러나 할당 속성과 속성간에 전혀 차이가없는 이유는 설명하지 않습니다. 두 경우 모두 메모리 사용량이 증가해야합니다. 그런데 assign 속성을 사용하는 경우 dealloc에서 릴리스를 수행하면 세그먼트 화 오류가 트리거됩니다. dealloc에서 릴리스를 수행하는 경우 대신 retain 특성을 사용해야합니다. – jyavenard