NSView/NSViewController 内存管理

NSView/NSViewController memory management

在一个非常简单的测试应用程序中,我在 appdelegate 中有一个 NSViewController(强烈保留)。我把这个 NSView 放在我的 NSWindow 的 contentView 中(我已经在 Interface Builder 中设置为 Release on Close)。但是,当我退出应用程序时,永远不会调用 NSView 的 dealloc 方法。我原以为它会被以下流程调用 - NSWindow dealloc -> 删除内容视图 -> 删除所有子视图。 此外,除非我将对它的强引用设置为在 AppDelegate 的 applicationWouldTerminate 方法中为 nil,否则不会释放 TestViewController。同样,我本以为它会被释放。但是,看起来 AppDelegate 从未被释放。 在我对 Objective-C 内存管理的理解中,我一定遗漏了一些基本知识。可能是因为在 Mavericks 上 Apple 强制退出应用程序,因此没有清理?我很感激被指出正确的方向。谢谢

我的代码

#import "AppDelegate.h"

@interface TestView : NSView
@end

@implementation TestView

- (void)dealloc { NSLog(@"TestView - Dealloc"); }

@end

@interface TestViewController : NSViewController

@end

@implementation TestViewController

- (void)loadView { self.view = [[TestView alloc] init]; }

- (void)dealloc { NSLog(@"TestViewController - dealloc"); }

@end

@interface AppDelegate ()

@property (weak) IBOutlet NSWindow* window;
@property (strong) TestViewController* testViewController;

@end

@implementation AppDelegate

- (void)dealloc { NSLog(@"AppDelegate - dealloc"); }

- (void)applicationDidFinishLaunching:(NSNotification*)aNotification
{
    // Insert code here to initialize your application
    TestViewController* testViewController = [[TestViewController alloc] init];
    self.testViewController = testViewController;

    [self.window.contentView addSubview:testViewController.view];
}

- (void)applicationWillTerminate:(NSNotification*)aNotification
{
    // Insert code here to tear down your application
    // self.testViewController = nil;
}

@end

应用程序终止不会清理所有单个对象。当进程终止时,OS X 内核简单地回收进程使用的所有资源。这样快多了。

来自Advanced Memory Management Programming Guide

When an application terminates, objects may not be sent a dealloc message. Because the process’s memory is automatically cleared on exit, it is more efficient simply to allow the operating system to clean up resources than to invoke all the memory management methods.

如果您确实有一些事情确实需要在应用程序终止之前完成,请将其放入应用程序委托的 -applicationWillTerminate: 方法中,或者观察应用程序对象发布的 NSApplicationWillTerminateNotification 通知。此外,您不需要选择加入 sudden termination 或者,如果您的应用通常选择加入它,只要它在终止时确实需要做一些事情,就暂时禁用它。