【发布时间】:2015-04-08 18:35:42
【问题描述】:
我正在为另一种编程语言开发一个 GUI 框架,它可以让我以本地后端为目标,即 Windows 上的 Windows API、Mac OS X 上的 Cocoa 和其他 Unix 系统上的 GTK+。框架的实际内容仍然是 C 和 Objective-C。我知道我正在做的事情与正常的 Cocoa 方式相反,但我不知道其他平台有更好的解决方案。
对于每个 UI 对象(窗口、按钮等),我都需要一定数量的私有数据结构,通常是一两个。您可以将这些视为控制器对象的数据字段。有函数uiWindowDestroy() 和uiControlDestroy() 会立即破坏窗口/控件,释放进程中的数据结构。 (在 Objective-C 的情况下,释放控件是通过调用 release 来实现的。)当它们所在的窗口关闭(不仅仅是隐藏/排序)或它们的窗口/控件时,也应该释放数据结构是被明确销毁的孩子。在 Windows 上,我通过处理 WM_DESTROY 来做到这一点;在 GTK+ 上,我通过连接到 "destroy" 来做到这一点。这两个选项都可以处理这两种情况。
我不确定如何使用 Cocoa 来处理这个问题。我知道控制器/视图关系应该是相反的。我知道有了这样的关系,我的显式销毁函数很容易,但是对我来说,父对象的自动销毁并不明显。
现在,这就是我尝试过的:我的 NSWindow 使用自定义 NSView 子类作为内容视图,它在dealloc 中触发其子类销毁。我还对 NSButton 进行了子类化,以释放 dealloc 中的数据结构。最后,我的 NSWindow 调用了setReleasedWhenClosed:YES,窗口委托在windowWillClose: 中调用了[self relase]。所有这些(子)类在alloc 和dealloc 中都有特殊代码,用于打印正在发生这样的分配/解除分配。
这是我在 10.9 上通过单击标题栏中的关闭按钮关闭窗口(有两个按钮和一个不受 NSView 支持的伪控件)时得到的结果:
0x7fce53c1a030 alloc uiWindow (window private data; malloc())
0x7fce53c3d670 alloc uiContainer (window content view; NSView)
0x7fce53c0eed0 alloc uiWindowDelegate (window delegate; NSObject)
0x7fce53c0f770 alloc stack (viewless control; malloc())
0x7fce53c195f0 alloc uiSingleViewControl (button private data; malloc())
0x7fce53c0abb0 alloc uiSingleViewControl (button private data; malloc())
0x7fce53c3d0e0 alloc uiControl *[] (viewless control private data; malloc())
0x7fce53c1b8b0 alloc int[] (same)
0x7fce53c0ed10 alloc intmax_t[] (same)
0x7fce53c3bda0 alloc intmax_t[] (same)
0x7fce53c1a030 free
0x7fce53c0eed0 free
如您所见,没有任何自定义控件与 NSWindow 一起被销毁。
我发现this question 表明在应用程序终止的情况下,默认的自动释放池不会被耗尽;我尝试将各种release 调用包装在@autoreleasepool 块中,但这也不起作用;输出是一样的。
所以我想知道是否有可靠的方法来做我想做的事。我知道当一个对象被释放时没有发送通知,也没有办法监视一个,我很困惑为什么我的辅助 Objective-C 对象没有被释放。理想情况下,我会完全避免将 NSButton 和其他子类化...
感谢理解。
【问题讨论】:
标签: objective-c cocoa object-lifetime