我可以使用自动释放来修复此内存泄漏吗?

时间:2011-06-06 00:04:51

标签: objective-c cocoa-touch ios memory-management memory-leaks

我的iPhone应用程序中有内存泄漏。我使用从Google下载的示例代码将Google AdMob添加到了我的应用中。但是,我很难进入测试模式,所以我添加了一个额外的变量如下:

GADRequest *r = [[GADRequest alloc] init];
r.testing = YES;
[bannerView_ loadRequest:r];

我使用Instruments发现了内存泄漏。 Instruments没有引导我到这行代码,它只是将我转储到main.m文件中。然而,当我注释掉与AdMob相关的代码时,泄漏消失了,我知道我已经没有注意释放这个新变量了。我只是不确切地知道如何释放它。变量r未在头文件中进行处理,因此这是处理它的所有代码。

我尝试添加:

- (void)dealloc {
[r release];
....
}

但是这导致了构建错误,说“'r'未声明”。这很奇怪,因为它让我觉得我在上面的第一个引用行中声明r,但我猜这是错的。任何帮助将非常感激。我真的试图教育自己内存泄漏,但我仍然觉得它们很混乱。

3 个答案:

答案 0 :(得分:4)

如果您的r是本地声明的(看起来,从您的代码片段判断),则无法从其范围之外访问它(此处:声明它的方法)。 您需要通过将其声明为ivar来使其在类实例中可访问。

声明它是一个ivar看起来像这样:

@interface YourClass : SuperClass {
    GADRequest *request;
}

//...

@end

然后将代码更改为:

request = [[GADRequest alloc] init];
request.testing = YES;
[bannerView_ loadRequest:request];

另请不要忘记在dealloc中发布它:

- (void)dealloc {
    [request release];
    //...
}

然而,在这种情况下,这是你想要的东西(我刚刚将其包括在内,以澄清为什么你得到关于r未被宣布的警告)。

您(很可能)在您的代码段运行后第二次不需要request,因此将其存储在ivar中只会不必要地占用RAM并为您的班级添加不必要的复杂性。你只需要在创建之后立即需要相应地处理(释放),这是在同一范围内。


你真正想做的是简单地(自动)发布,妥善处理它。

请注意,只要有需要,loadRequest:需要保留 r 。当然, Apple的实施就是这样做。但是有一天你可能想要自己写一个类似的方法,所以记住这一点

GADRequest *r = [[GADRequest alloc] init];
r.testing = YES;
[bannerView_ loadRequest:r];
[r release]; //or: [r autorelease];

答案 1 :(得分:4)

添加[r release];在代码正下方:

GADRequest *r = [[GADRequest alloc] init];
r.testing = YES;
[bannerView_ loadRequest:r];
[r release];

变量r仅在代码的那一部分声明,因此它应该被释放。释放的目的是在你不再需要它时尽快摆脱它,所以上面应该适合你。

答案 2 :(得分:0)

OP在这里。感谢所有详细而深思熟虑的回复。这无疑有助于更好地处理内存管理。我完全按照建议完成,添加[r release];在发布的代码正下方。但是,我仍然有泄漏。我把它隔离成一行代码。以下泄漏:

GADRequest *r = [[GADRequest alloc] init];
r.testing = YES;
[bannerView_ loadRequest:r];
[r release];

以下不泄漏:

GADRequest *r = [[GADRequest alloc] init];
r.testing = YES;
// [bannerView_ loadRequest:r];
[r release];

我想我正在使用loadRequest更改bannerView上的保留计数,但我不知道如何修复它。我在[r release]之后立即尝试了[bannerView_ release];线(即本地释放),但不起作用。我没想到它因为bannerView_在其他地方宣布。我试过[bannerView_ release];在dealloc方法但但是没有用。我也试过[bannerView_ autorelease];本地。谷歌的明智负责人放了[bannerView_ release];在ViewDidUnload方法中。

仪器可能只是弄乱我的脑袋。泄漏在大约10秒后出现,但应用程序运行良好,并且随着应用程序继续运行,泄漏的内存量似乎没有螺旋式上升。是否有良性内存泄漏这样的事情?

再次感谢您的帮助,

Dessie。