我注意到我写的程序的内存使用量随着时间的推移而不断增加。 XCode的工具显示没有内存泄漏,但你可以看到堆栈随着时间的推移而增长..
经过调查,很多内存使用来自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 *旋转对象未正确释放,其内存占用将继续增长。
但是,如果我将代码更改为: 头:
@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对象不会留下任何东西
我无法弄清楚为什么在这里有一个不同的属性会有所不同,它只是没有意义!除非我大量误解了正在发生的事情。
任何解释都会受到欢迎。
由于
答案 0 :(得分:3)
您需要在dealloc方法中释放对象:
-(void)dealloc {
[webView release];
[backButton release];
[forwardButton release];
[URL release];
[spin release];
[super dealloc];
}
在第二个版本中没有出现问题的原因是,您使用属性assign设置属性,通常您应该使用retain for“object-properties”assign通常用于基本数据类型,如int,漂浮,布尔等...
编辑:
到具有retain和assign的部分,afaik的行为如下: 如果属性是使用assign,则设置
self.thatVariable = something;
与:
相同
thatVariable = something;
如果您使用保留它将与:
相同
[thatVariable release];
thatVariable = [something retain];
因此,如果您使用assign来保存指向对象指针的变量,那么您的对象就不能在其他地方解除分配,这将导致访问不良。
Afaik使用assign with object的唯一理由是得到一个弱引用。如果你必须保持彼此保留的对象,那么它们都不会被释放。这就是你将使用分配给对象的地方。 (例如,通常在委托模式中。对象将保留它的委托,委托将保留该对象。在这种情况下,委托通常被分配)