Reputation: 2095
I have noticed that the memory usage of a program I wrote, keep increasing over time. XCode's instruments shows no memory leak, yet you can see the heap stack growing over time..
Upon investigation, a lot of the memory usage come from the IBOutlet UI objects. The interface is build with Interface Builder.
Typical usage would be like:
header:
@interface HelpViewController : UIViewController <UIWebViewDelegate> {
IBOutlet UIWebView *webView;
IBOutlet UIBarItem *backButton;
IBOutlet UIBarItem *forwardButton;
NSString *URL;
IBOutlet UIActivityIndicatorView *spin;
}
@property (nonatomic, retain) NSString *URL;
And for the usage :
- (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];
}
Looking at the heap stack, you find that the UIActivityIndicatorView *spin object isn't properly deallocated, and its memory footprint will keep growing.
However, if I change the code to: 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;
And in the code I do:
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];
}
Nothing more, nothing else, then the heap stack doesn't grow anywhere as much.. and the UIActivityIndicatorView object doesn't leave any stuff behind
I can't figure out why it would make a difference here having an assign property or not, it just doesn't make sense ! Unless I massively misunderstood what's happening.
Any explanations would be welcomed..
Thanks
Upvotes: 0
Views: 555
Reputation: 5519
You need to release the objects in the dealloc method:
-(void)dealloc {
[webView release];
[backButton release];
[forwardButton release];
[URL release];
[spin release];
[super dealloc];
}
The reason why the problem doesn't occour in your second version is, that you set the property with the attribute assign, usually you should use retain for "object-properties" assign is usually used for the basic datatypes like int, float, bool etc...
EDIT:
to the part with retain and assign, afaik the behaviour is the following: If the property is made with assign, then setting
self.thatVariable = something;
would be the same as:
thatVariable = something;
if you used retain it would be the same as:
[thatVariable release];
thatVariable = [something retain];
So if you used assign for variables that hold pointers to objects you can't be sure, that your object isnt deallocated somewhere else, which would result in a bad access.
Afaik the only reason to use assign with object is to get a weak reference. If you have to object which would both retain each other, none of it would ever get released. so thats a spot where you would use assign for objects. (f.e. often in the delegate-pattern. the object would retain it's delegate and the delegate would retain the object. In this case the delegate is often assigned)
Upvotes: 2