【问题标题】:Why is Instruments reporting memory leaks in this code?为什么 Instruments 在此代码中报告内存泄漏?
【发布时间】:2011-04-01 08:56:36
【问题描述】:

快速提问,Instruments 报告这里有泄漏...

MyViewController *myVC = [[MyViewController alloc] initWithNibName:@"myView" bundle:nil];     
[self.navigationController pushViewController:myVC animated:YES];  //<<<<---- !00% leak according to Instruments
[myVC release];

我知道 myVC 由导航控制器保留,所以我假设导航控制器在视图从导航堆栈中弹出时释放它们?

另外,在我的一个循环中还有一个棘手的问题,静态分析器在这里报告潜在的泄漏......

//Walk through the scheduled alarms and create notifications
NSMutableArray *fireDates = [[NSMutableArray alloc] init];
for(NSDate *fireDate in fireDates)          //<<<<---- Static analyzer is reporting potential leak here
{
     UILocalNotification *localNotif = [[UILocalNotification alloc] init];
    if (localNotif == nil)
    {
        [fireDates release];
        return;
    }

    localNotif.fireDate = fireDate;  
    localNotif.timeZone = [NSTimeZone defaultTimeZone];

    localNotif.alertBody = [NSString stringWithFormat:@"%@", alarm.Label];
    localNotif.alertAction = NSLocalizedString(@"Launch", nil);

    localNotif.soundName = UILocalNotificationDefaultSoundName;

    localNotif.userInfo = infoDict;
    localNotif.repeatInterval = NSWeekCalendarUnit;

    [[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
    [localNotif release];

}
[fireDates release];

我需要以某种方式释放 fireDate 吗?

提前感谢您的帮助!

【问题讨论】:

  • 静态分析器一般都很好...也许不要省略缺少的代码...
  • 谢谢,Eiko,我刚刚更新了我的问题以包含缺失的代码。你的想法?
  • 您是针对模拟器还是设备运行测试?我注意到,针对模拟器,泄漏程序显示错误泄漏。
  • @joo - 我正在对模拟器进行测试。我会在我的设备上试试,谢谢。
  • @joo - 我在设备上试过了,同样的导航控制器泄漏仍然被捕获。你的想法?

标签: iphone ipad memory-management ios instruments


【解决方案1】:

这些 sn-ps 都很好,就像 sn-ps 一样。如果没有看到您的完整代码,就不可能说您是否没有在其他地方做一些愚蠢的事情。您是否曾经发布过您的 navigationController(可能在您的应用程序委托 -dealloc 中)?这是一个没有太大意义的泄漏,但它可能是触发第一个警告的原因。


编辑:关于第二个 sn-p,代码看起来不错(尽管快捷方式返回的情况会困扰一些程序员,他们宁愿看到 break 语句)。静态分析器可能会因条件返回中缺少[localNotif release](尽管它显然是不必要的)而感到困扰。

【讨论】:

  • 谢谢,西莫!不,我不会在我的应用程序委托的 -dealloc 中释放我的导航控制器,因为导航控制器是在我的 nib mainwindow.xib nib 文件中创建的。因此,我不应该在我的 -dealloc 中释放它,对吧?
  • 你有设置导航控制器的插座吗?
  • @christo16 - 不,我没有,因为我的导航控制器没有实例变量。我只是将 [self navigationController] 用于所有内容。你的想法?
  • 如果您在 nib 中有一个根视图,但它不在 IBOutlet 中,我不知道是什么代码释放了它。我怀疑这实际上是您的泄漏。尝试将 IBOutlet ivar 或属性添加到您的应用程序委托类并在 -dealloc 中发布它。即使不是这种情况,它也是一个有用的数据点,而且它是对您的代码的微小更改。
  • return 语句肯定会触发静态分析器——如果localNotif 的分配失败,则会发生fireDates 的简单内存泄漏。
【解决方案2】:

在第一个sn-p中,泄露了什么? Instruments 会告诉你分配它的行,这通常不是对泄漏“负责”的行(当然,行号往往是关闭的,因为它给你的是返回地址,而不是调用地址)。我假设它是 MyViewController 被泄露,并且该仪器实际上在抱怨 alloc(查看回溯,我认为是 cmd-E)。

如果您单击内存地址旁边的箭头(您可能需要单击一下并将鼠标悬停在泄漏地址上;我不记得了)您会看到所有的 alloc/retain/release/autorelease/ malloc/free/CFRetain/CFRelease 调用该地址。忽略 alloc 之前的那些(那些是针对碰巧位于同一地址的先前对象)。匹配保留和(自动)释放。您可以将自动释放与相应的(延迟)释放相匹配,因为延迟释放将在 NSAutoreleasePool 释放时发生(这在堆栈跟踪中很明显)。寻找没有匹配(自动)释放的保留。这就是泄漏。

在第二种情况下,如果您告诉我们 Clang SA 告诉您的内容会有所帮助(单击左侧的小三角形,它会展开以向您显示发生泄漏的控制流)。

但我认为循环根本不会运行,因为fireDates 是空的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-23
    • 2015-07-14
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多