为什么我的财产可能存在泄漏?我该如何修复它?
我的 UIViewController 中有一个 UIScrollView 在我的 .h 文件中定义如下:
#import <UIKit/UIKit.h>
@interface TestViewController : UIViewController <UIScrollViewDelegate>
@property (nonatomic, retain) UIScrollView * imageScrollView;
@end
然后在我的 .m 文件中我有以下内容:
@synthesize imageScrollView = _imageScrollView;
我读到这将自动创建 _imageScrollView我通常会输入 .h 文件吗? (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 上......
I have a UIScrollView in my UIViewController defined as this in my .h file:
#import <UIKit/UIKit.h>
@interface TestViewController : UIViewController <UIScrollViewDelegate>
@property (nonatomic, retain) UIScrollView * imageScrollView;
@end
Then in my .m file I have the following:
@synthesize imageScrollView = _imageScrollView;
I read that this will automatically create the _imageScrollView that I would normally type in the .h file? (UIScrollView * _imageScrollView)
I like it, because it removes duplicate code from my .h files. Now in my loadView I do the rest:
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)];
And in the dealloc release and nil:
- (void)dealloc
{
[_imageScrollView release], _imageScrollView = nil;
[super dealloc];
}
Now after a build Xcode is telling me this:
Potential leak of an object allocated on line #linenumber
This will go away when I change this:
self.imageScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0 - 20.0 - 49.0)];
to this:
self.imageScrollView = [[[UIScrollView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 480.0 - 20.0 - 49.0)] autorelease];
Why do I need to autorelease this when I'm release it in dealloc? What am I doing wrong?
This memory warning only occurs in Xcode on my iMac with Lion installed, not on my macbook with snow leopard...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是因为您的
imageScrollView
属性被声明为retain
属性。这意味着当您设置它时,访问器(由@synthesize
生成)会自动保留该值。如果您不希望出现此行为,则应将您的属性声明为assign
。 (但是在这种情况下您确实想要这种行为。)无论如何,因此您的对象被保留两次,一次在您的代码中,一次由访问器保留,所以它永远不会被释放。永远记住
self.imageScrollView =
就像[self setImageScrollView:]
一样,而且这些事情就发生在那里!(最后,内存警告仅发生在 Lion 上,因为旧的 Xcode 没有注意到该错误,而不是因为该错误不存在。)
It's because your
imageScrollView
property is declared to be aretain
property. This means that when you set it, the accessor (which is generated by@synthesize
) automatically retains the value. If you don't want this behavior, you should declare your property to beassign
. (But you do want this behavior in this case.)Anyway, thus your object is retained twice, once in your code, and once by the accessor, so it's never released. Always remember that
self.imageScrollView =
is just like[self setImageScrollView:]
, and that stuff happens in there!(And last, the memory warning only occurs on Lion because the old Xcode isn't noticing the error, not because the error isn't there.)
您已使用
retain
选项定义了您的属性。这意味着当您将一个对象分配给该属性时,它将被保留——您“取得了该对象的所有权”。在这种情况下这很好,因为您希望 UIScrollView 在您需要时保留下来。我应该指出,您还拥有从名称以alloc
、new
、copy
或mutableCopy
开头的方法返回的任何对象代码>.因此,查看您的代码,您可以看到您拥有使用
alloc
创建的UIScrollView
,但在存储它时您再次声明所有权在财产中。这意味着内存将永远不会被回收。通过调用autorelease
,您可以在将对象分配给属性之前放弃该对象的所有权,这意味着在dealloc
中调用release
将按预期工作。我建议您阅读 内存管理编程指南 和 Objective-C 的声明属性部分编程语言文档。
You've defined your property with the
retain
option. This means that when you assign an object to that property, it will be retained—you "take ownership" of the object. That's good in this case, because you want theUIScrollView
to stick around while you need it. I should note that you also own any object returned from methods whose name begins withalloc
,new
,copy
, ormutableCopy
.So, looking at your code you can see that you own
UIScrollView
that you create withalloc
, but then you claim ownership again when you store it in the property. This means that the memory will never be reclaimed. By callingautorelease
, you relinquish ownership of the object before assigning it to the property, meaning that callingrelease
indealloc
will work as intended.I suggest you read over the Memory Management Programming Guide and the Declared Properties section of The Objective-C Programming Language document.