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

Objective c 我可以使用自动释放修复此内存泄漏吗?,objective-c,cocoa-touch,ios,memory-management,memory-leaks,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不会引导我找到这行代码,它只是将我转储到main.m文件中。然而,当我注释掉与AdMob相

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

GADRequest *r = [[GADRequest alloc] init];
r.testing = YES;
[bannerView_ loadRequest:r];
我用仪器发现内存泄漏。Instruments不会引导我找到这行代码,它只是将我转储到main.m文件中。然而,当我注释掉与AdMob相关的代码时,泄漏消失了,我知道的足够多,我没有注意释放这个新变量。我只是不知道该怎么发布它。变量
r
未在头文件中寻址,因此这是所有处理该变量的代码

我试着加上:

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

但这导致了一个生成错误,即“r”未声明。这很奇怪,因为在我看来,我在上面引用的第一行中声明了
r
,但我想这是错误的。任何帮助都将不胜感激。我确实试着让自己了解内存泄漏,但我仍然发现它们非常令人困惑。

如果您的
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
未声明的警告)

在代码段运行后,您(很可能)不需要第二次请求,因此将其存储在ivar中只会不必要地占用RAM,并给类增加不必要的复杂性。您只需要在创建后立即使用的东西应该得到相应的处理(发布),这是在相同的范围内


实际上,您需要做的是简单地(自动)释放它,并妥善保管它

请记住,您的
加载请求:
将需要保留
r
,只要它需要就可以当然,苹果的实现做到了这一点。但是有一天你可能想自己写一个类似的方法,所以请记住这一点

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

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

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

变量r仅在代码的该部分声明,因此应该在该部分发布。释放的目的是在你不再需要它的时候就把它扔掉,所以上面的方法对你来说应该是完美的。

OP here。感谢所有详细和周到的回复。这无疑有助于更好地处理内存管理。我完全按照建议做了,添加了[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发布]之后,我立即尝试了[bannerView_uuu发布];行(即在本地发布),但这不起作用。我没想到会这样,因为bannerView_uu是在别处声明的。我试过[释放bannerView];在dealloc方法中,但这不起作用。我还尝试了[bannerView_uuu自动释放];在当地。谷歌的智者们发布了[bannerView_uu发布];在ViewDidUnload方法中

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

再次感谢你的帮助


Dessie.

XenElement的答案是一个更好的解决方案:
r
不需要超出此范围,因此它不需要是ivar
bannerView\uuz
将以它通常处理其请求对象的任何方式保留它,这应该是明智的,因为依赖其他人来保留它将是不好的代码;无需不必要地将其放入自动释放池中,直到运行循环结束(或池排放)才会释放,因为在
[bannerView\uuuuuuloadrequest:r]
行之后的任何时候都不需要它。我完全知道,将其作为ivar并不是OP想要的。不过我把它包括进来是为了解释他的编译器警告。不过,我们应该更清楚地表明,本地版本将是一个合适的解决方案。至于自动释放:Cocoa中的大多数方法都返回自动释放的对象,所以这并不少见。谷歌甚至在他们的网站中加入了一个
自动释放功能。鉴于OP对ObjC来说似乎是一个新手,我不认为他知道方法a
loadRequest:
必须保留args,因此值得一提,imho。我要明确的是,我没有对你的答案或任何东西投反对票,只是表达了我的观点。我同意这样的解释是最好的,我只是觉得ivar的建议可能会让他走上错误的道路。我知道autorelease在很多地方都有使用,谷歌使用它并不令人震惊,因为我想,他们的大多数程序员都来自垃圾收集的背景。不过,我仍然认为,学会每次有机会时手动释放比依赖自动释放更好,因为后者会让你陷入真正的麻烦(即使不是在这里)。我应该在回答中更清楚地说明ivar“解决方案”这仅仅是对他的编译器警告的一种教育性修复,而不是对他的问题的正确解决。我同时更新了我的答案。现在应该清楚了。事实上,我也尝试在适当的时候使用手动释放哦,别担心,即使你投了反对票,你也有好的观点