IBOutlet, использование свойств члена или нет?утечка памяти? - PullRequest
1 голос
/ 27 июля 2010

Я заметил, что использование памяти программой, которую я написал, со временем увеличивается.Инструменты XCode не обнаруживают утечку памяти, но вы можете видеть, как со временем стек кучи увеличивается.

После исследования большая часть использования памяти поступает от объектов пользовательского интерфейса IBOutlet.Интерфейс построен с помощью Interface Builder.

Типичное использование будет выглядеть следующим образом:

header:

@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 * не был должным образом освобожден, и его объем памяти будет расти.

Однако, если я изменю код на: header:

@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 не оставляет ничегопозади

Я не могу понять, почему это будет иметь значение, если у вас есть свойство assign или нет, это просто не имеет смысла!Если только я не очень неправильно понял, что происходит.

Любые объяснения будут приветствоваться ..

Спасибо

1 Ответ

3 голосов
/ 27 июля 2010

Вам нужно освободить объекты в методе dealloc:



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

Причина, по которой проблема не возникает в вашей второй версии, заключается в том, что вы устанавливаете свойство с помощью атрибута assign, обычно вы должны использовать retain для присвоения «object-properties», как правило, используется для основных типов данных, таких как int, float, bool и т.д ...

EDIT:

для части с сохранением и назначением, afaik, поведение выглядит следующим образом: Если свойство сделано с помощью assign, тогда настройка


self.thatVariable = something;

будет таким же, как:


thatVariable = something;

если бы вы использовали retain, это было бы так же, как:


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

Так что, если вы использовали для переменных переменные, которые содержат указатели на объекты, вы не можете быть уверены, что ваш объект не освобожден в другом месте, что приведет к плохому доступу.

Афайк, единственная причина использовать присвоение с объектом - получить слабую ссылку. Если вам придётся возражать, которые оба сохранят друг друга, ни один из них никогда не будет выпущен. так что это место, где вы могли бы использовать для объектов назначить. (например, часто в шаблоне делегата. объект сохранит свой делегат, а делегат сохранит объект. В этом случае делегат часто назначается)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...