代码之家  ›  专栏  ›  技术社区  ›  Nathan S.

追踪cocoa内存泄漏

  •  2
  • Nathan S.  · 技术社区  · 15 年前

    我收到应用程序内存泄漏的报告,但我无法准确追踪到底发生了什么。我有一个函数,它取出旧视图并在新视图中交换。我没有使用NavController或任何@properties;我直接管理我的顶级窗口。

    -(void)swapInView:(UIViewController*)newViewController
    {
        [currentViewer.view removeFromSuperview];
        printf("Old viewController (%p) has count of %d; now releasing\n",
            currentViewer, [currentViewer retainCount]);
        [currentViewer release];
        currentViewer = 0;
    
        currentViewer = newViewController;
        [currentViewer retain];
    
        [mainWindow addSubview:currentViewer.view];
        [mainWindow bringSubviewToFront:currentViewer.view];
    }
    

    运行代码时,我显示当前视图控制器正在被释放,然后调用该视图控制器的dealloc方法。但是,仪器/泄漏仍然报告为泄漏。例如,我打印出以下内容:

    Old viewController (0x119f80) has count of 1; now releasing
    Deallocating WelcomeScreenViewController
    

    MyViewController *theViewController = [[MyViewController alloc]
                                            initWithNibName:nil
                                                     bundle:nil];
    [GameMaster swapInNewView:theViewController];
    [theViewController release];
    

    有人对如何追踪正在发生的事情有什么建议吗?我使用的是3.1.2SDK,但我在早期的SDK中也看到了这一点。

    2 回复  |  直到 15 年前
        1
  •  3
  •   James Eichele Bernard Igiri    15 年前

    呵呵。这是一个有趣的。我写了一个快速测试,以确保我们两个都不是疯子。

    最后,一切都归结于调用代码:

    [[MyViewController alloc] initWithNibName:nil bundle:nil];
    

    初始化视图控制器时,其 view 对象尚未定义,在请求之前将不会定义。

    nil 对于nib名称,必须重写 loadView UIViewController 子类以正确设置视图对象。看见 Apple's documentation 详情请参阅。

    的默认实现 负荷视图 很明显,它会在幕后施展魔法,而这种魔法会导致内存泄漏。

    所以:当你打这个电话时:

    [mainWindow addSubview:currentViewer.view];
    

    你真的在做什么

    一: currentViewer.view [currentViewer loadView]
    二: [mainWindow addSubview:...]

    要验证,只需修改 负荷视图 方法在您的自定义 UIViewController

    - (void)loadView
    {
        [self setView:[[UIView new] autorelease]];
    }
    

    这将防止调用默认值 现在已经没有泄漏了。

    ,或使用笔尖。

        2
  •  0
  •   Mark    15 年前

    取消接收器与其superview和窗口的链接,将其从响应器链中删除,并使其光标矩形无效。接收器也被释放“

    [exampleViewController.view removeFromSuperview];
    [exampleViewController release];
    

    在我的应用程序中,由于过度释放对象而导致延迟崩溃。