IBOutlet,是否使用会员资产?内存泄漏?

时间:2010-07-27 11:35:39

标签: iphone objective-c xcode

我注意到我写的程序的内存使用量随着时间的推移而不断增加。 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];
}

查看堆栈,您会发现UIActivityIndi​​catorView *旋转对象未正确释放,其内存占用将继续增长。

但是,如果我将代码更改为: 头:

@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对象不会留下任何东西

我无法弄清楚为什么在这里有一个不同的属性会有所不同,它只是没有意义!除非我大量误解了正在发生的事情。

任何解释都会受到欢迎。

由于

1 个答案:

答案 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的唯一理由是得到一个弱引用。如果你必须保持彼此保留的对象,那么它们都不会被释放。这就是你将使用分配给对象的地方。 (例如,通常在委托模式中。对象将保留它的委托,委托将保留该对象。在这种情况下,委托通常被分配)