为什么我的财产是潜在的泄漏,我该如何解决?

时间:2011-08-13 05:53:01

标签: objective-c xcode properties release

我的.h文件中定义的 UIViewController 中有 UIScrollView

#import <UIKit/UIKit.h>

@interface TestViewController : UIViewController <UIScrollViewDelegate>

@property (nonatomic, retain) UIScrollView * imageScrollView;

@end

然后在我的.m文件中,我有以下内容:

@synthesize imageScrollView = _imageScrollView;

我读到这会自动创建我通常在.h文件中输入的_imageScrollView吗? (UIScrollView * _imageScrollView)

我喜欢它,因为它从我的.h文件中删除了重复的代码。现在在我的 loadView 中,我完成剩下的工作了:

self.imageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0 - 20.0 - 49.0)];
[_imageScrollView setDelegate:self];
[_imageScrollView setPagingEnabled:YES];
[_imageScrollView setBounces:NO];
[_imageScrollView setShowsHorizontalScrollIndicator:NO];
[_imageScrollView setShowsVerticalScrollIndicator:NO];
[_imageScrollView setContentSize:CGSizeMake(320.0 * 3.0, 480.0 - 20.0 - 49.0)];

dealloc 版本和nil:

- (void)dealloc
{
[_imageScrollView release], _imageScrollView = nil;

[super dealloc];
}

现在,在构建Xcode之后告诉我:

Potential leak of an object allocated on line #linenumber

当我改变这个时,这将会消失:

self.imageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0 - 20.0 - 49.0)];

到此:

self.imageScrollView = [[[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0 - 20.0 - 49.0)] autorelease];

为什么我在dealloc中释放它时需要自动释放?我做错了什么?

此内存警告仅发生在安装了Lion的iMac上的Xcode中,而不是发布在带有雪豹的Macbook上...

2 个答案:

答案 0 :(得分:2)

这是因为您的imageScrollView属性被声明为retain属性。这意味着当您设置它时,访问者(由@synthesize生成)会自动保留该值。如果您不想要此行为,则应将您的属性声明为assign。 (但是你在这种情况下需要这种行为。)

无论如何,你的对象被保留两次,一次在你的代码中,一次由访问者保留,所以它永远不会被释放。永远记住,self.imageScrollView =就像[self setImageScrollView:]一样,那些东西发生在那里!

(最后,内存警告只发生在Lion上,因为旧的Xcode没有注意到错误,不是因为错误不在那里。)

答案 1 :(得分:2)

您已使用retain选项定义了您的媒体资源。这意味着当您将对象分配给该属性时,它将被保留 - 您“拥有”该对象的所有权。在这种情况下这很好,因为你希望UIScrollView在你需要的时候留下来。我应该注意,您还拥有从名称以allocnewcopymutableCopy开头的方法返回的任何对象。

因此,查看您的代码,您可以看到自己使用UIScrollView创建的alloc,但是当您将其存储在属性中时,您会再次声明所有权 。这意味着永远不会回收内存。通过调用autorelease,您可以在将对象分配给属性之前放弃该对象的所有权,这意味着在release中调用dealloc将按预期工作。

我建议你阅读Objective-C编程语言文档的Memory Management Programming GuideDeclared Properties部分。