为什么我的财产可能存在泄漏?我该如何修复它?

发布于 2024-11-29 15:36:04 字数 1710 浏览 1 评论 0原文

我的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

落花随流水 2024-12-06 15:36:04

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

无论如何,因此您的对象被保留两次,一次在您的代码中,一次由访问器保留,所以它永远不会被释放。永远记住 self.imageScrollView = 就像 [self setImageScrollView:] 一样,而且这些事情就发生在那里!

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

It's because your imageScrollView property is declared to be a retain 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 be assign. (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.)

风向决定发型 2024-12-06 15:36:04

您已使用 retain 选项定义了您的属性。这意味着当您将一个对象分配给该属性时,它将被保留——您“取得了该对象的所有权”。在这种情况下这很好,因为您希望 UIScrollView 在您需要时保留下来。我应该指出,您还拥有从名称以 allocnewcopymutableCopy 开头的方法返回的任何对象代码>.

因此,查看您的代码,您可以看到您拥有使用 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 the UIScrollView to stick around while you need it. I should note that you also own any object returned from methods whose name begins with alloc, new, copy, or mutableCopy.

So, looking at your code you can see that you own UIScrollView that you create with alloc, but then you claim ownership again when you store it in the property. This means that the memory will never be reclaimed. By calling autorelease, you relinquish ownership of the object before assigning it to the property, meaning that calling release in dealloc 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文