简短版本:
release
为什么Cocoa 应用程序终止时 NSView 对象的子视图没有发送消息?- 有没有办法覆盖这种行为?
一个例子:
下面展示的MyView
类只不过是一个NSView
子类,它在创建和销毁时向控制台报告。我已经对其进行了测试,发现它可以正常工作。但是,当我按照我的应用程序委托的下一个代码片段所示使用它时,我看到了一些意想不到的东西(请参阅示例输出)。
// MyView:
@interface MyView : NSView { }
@end
@implementation MyView
- (id)initWithFrame:(NSRect)frameRect
{
if ((self = [super initWithFrame:frameRect]) == nil) { return nil; }
NSLog(@"init %@", self);
return self;
}
- (void)dealloc
{
NSLog(@"dealloc %@", self);
[super dealloc];
}
@end
// Application delegate:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSLog(@"begin");
parentView = [[MyView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)];
MyView * myView = [[MyView alloc] initWithFrame:NSMakeRect(10, 10, 80, 80)];
[parentView addSubview:myView];
[myView release];
NSLog(@"run");
}
- (void)applicationWillTerminate:(NSNotification *)aNotification
{
NSLog(@"quit");
[parentView release];
NSLog(@"end.");
}
此应用程序产生以下输出:
开始
初始化<
我的视图:0x10013f840>
初始化我的视图<
:0x10261b620>
运行
退出
dealloc<
我的视图:0x10013f840>
结束。
问题:
我可以清楚地看到当应用程序退出时第一个视图对象正在被释放,并且我确定(经过测试和验证)NSView
对象在它们自己被释放时会自动释放它们的子视图。但是,在应用程序终止期间,这些子视图似乎没有被释放。
长版:(也就是为什么有人会关心?:)
首先让我说我熟悉正在运行的应用程序退出时释放内存的方式。我知道我的子视图将被妥善处理,即使它们从未发送过release
消息,所以我不担心这是泄漏。事实上,我很确定(但不是 100% 确定)我的问题 #1 的答案是:“因为在应用程序即将终止时释放子视图是不必要的。”
当我的应用程序在调试模式下运行时,我使用一些简单的手动代码来进行内存跟踪。我在所有自定义类的 and 方法中调用了一个 and 方法,并在我的应用程序的 Cocoa 部分完成后使用该函数报告Trace_Init()
任何Trace_Dealloc()
未发布的对象。我发现这比定期运行 Apple 的内存泄漏性能工具要简单得多。如果我在运行时导致内存泄漏,我会在我的应用程序退出后立即知道。init
dealloc
atexit()
但是,dealloc
终止期间没有调用意味着NSView
当我退出应用程序时,用作子视图的任何自定义子类都会显示为内存泄漏。因此,我的问题 #2 的原因。我想让 Cocoa 在终止期间释放所有内容,以便我的内存跟踪能够正确结束。自然,我只会覆盖调试模式下的默认行为。我发布的应用程序没有启用任何内存跟踪代码,并且应该能够像平常一样有效地退出。
就是这样!(呼)如果你做到了这一步,感谢你花时间阅读这一切。