首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IBOutlet,是否使用成员属性?内存泄漏?

IBOutlet,是否使用成员属性?内存泄漏?
EN

Stack Overflow用户
提问于 2010-07-27 19:35:39
回答 1查看 542关注 0票数 1

我注意到,我编写的程序的内存使用量随着时间的推移而不断增加。XCode的工具没有显示内存泄漏,但是您可以看到堆堆栈随着时间的推移而增长。

经过调查,大量内存使用来自IBOutlet UI对象。该界面是使用interface Builder构建的。

典型用法如下:

标题:

代码语言:javascript
复制
@interface HelpViewController : UIViewController <UIWebViewDelegate> {
    IBOutlet UIWebView    *webView;
    IBOutlet UIBarItem    *backButton;
    IBOutlet UIBarItem    *forwardButton;
    NSString    *URL;
    IBOutlet UIActivityIndicatorView *spin;
}

@property (nonatomic, retain) NSString *URL;

对于用法:

代码语言:javascript
复制
- (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 *spin对象没有正确释放,并且它的内存占用量将继续增长。

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

代码语言:javascript
复制
@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;

在代码中,我做到了:

代码语言:javascript
复制
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对象不会留下任何东西

我不明白为什么这里有一个赋值属性会有什么不同,它就是没有意义!除非我很大程度上误解了发生的事情。

欢迎任何解释..

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-07-27 23:35:08

您需要释放dealloc方法中的对象:

代码语言:javascript
复制
 -(void)dealloc {
   [webView release];
   [backButton release];
   [forwardButton release];
   [URL release];
   [spin release];
   [super dealloc];
}

在你的第二个版本中没有出现这个问题的原因是,你用赋值属性来设置属性,通常你应该使用"object-properties“赋值的保留,赋值通常用于基本的数据类型,如int,float,bool等……

编辑:

对于带有retain和assign的部分,afaik的行为如下:如果属性是通过assign创建的,则设置

代码语言:javascript
复制
self.thatVariable = something;

将与以下内容相同:

代码语言:javascript
复制
thatVariable = something;

如果您使用保留,它将与以下内容相同:

代码语言:javascript
复制
[thatVariable release];
thatVariable = [something retain];

因此,如果你为持有对象指针的变量使用了赋值,你就不能确定你的对象没有被释放到其他地方,这将导致错误的访问。

Afaik使用assign with object的唯一原因是为了获得弱引用。如果你不得不反对这两者都会相互保留,那么它们都不会被释放。这就是你可以使用assign for objects的地方。(f.e.通常在委托模式中。对象将保留其代理,而代理将保留该对象。在这种情况下,委派通常是指定的)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3343161

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档