gpt4 book ai didi

objective-c - 当标准 NSView 或 NSWindow 被破坏时,是否有可靠的方法来破坏私有(private)数据结构?

转载 作者:行者123 更新时间:2023-12-03 17:10:55 27 4
gpt4 key购买 nike

我正在为另一种编程语言开发一个 GUI 框架,它可以让我瞄准 native 后端,即 Windows 上的 Windows API、Mac OS X 上的 Cocoa 和其他 Unix 系统上的 GTK+。该框架的实际核心仍然是 C 和 Objective-C。我知道我所做的与正常的 Cocoa 方式相反,但我不知道对于其他平台有更好的解决方案。

对于每个 UI 对象(窗口、按钮等),我都需要一定数量的私有(private)数据结构,通常是一两个。您可以将它们视为 Controller 对象的数据字段。有函数 uiWindowDestroy() 和 uiControlDestroy() 可以立即销毁窗口/控件,从而释放进程中的数据结构。 (对于 Objective-C,释放控件是通过调用 release 来实现的。)当数据结构所在的窗口关闭(不仅仅是隐藏/排序)或它们作为子级的窗口/控件被显式销毁。在 Windows 上,我通过处理 WM_DESTROY 来做到这一点;在 GTK+ 上,我通过连接到“destroy”来做到这一点。这两个选项都可以处理这两种情况。

我不知道如何用 Cocoa 处理这个问题。我知道 Controller / View 关系应该是相反的。我知道通过这种关系,我的显式销毁函数很容易,但父对象的自动销毁对我来说并不明显。

现在,这就是我尝试过的:我的 NSWindow 使用自定义 NSView 子类作为内容 View ,这会在 dealloc 中触发其子级销毁。我还对 NSButton 进行了子类化,以在 dealloc 中释放其数据结构。最后,我的 NSWindow 调用了 setReleasedWhenClosed:YES ,并且窗口委托(delegate)在 windowWillClose: 中调用 [self relase] 。所有这些(子)类在 allocdealloc 中都有特殊的代码,打印出这样的分配/释放正在发生。

以下是我在 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 block 中,但这也不起作用;输出是相同的。

所以我想知道是否有一种可靠的方法来做我想做的事情。我知道当对象被释放时没有发送通知,也没有办法监视通知,而且我很困惑为什么我的助手 Objective-C 对象没有被释放。理想情况下,我根本不需要子类化 NSButton 和其他...

感谢您的理解。

最佳答案

如果窗口由窗口 Controller (NSWindowController 的实例或子类)控制,则 setReleasedWhenClosed:YES 无效。窗口 Controller 对其窗口具有强引用。

同样, View Controller 对其 View 具有强引用。

如果您想在窗口关闭时释放窗口,请务必在 -windowWillClose: 中释放窗口 Controller ,或者以其他方式响应 NSWindowWillCloseNotification 通知。同样,如果您有 View Controller ,则应在使用完它们后释放它们(而不是它们控制的 View )。

尽管如此,您通常不应该在内存管理上使用谓词控制代码。因为您不知道除了代码之外还有什么可以维护对对象的强引用,因此您无法知道释放引用将导致对象被释放。

相反,您应该将此类代码放入通知处理程序或委托(delegate)方法中,例如 -windowWillClose:NSWindowWillCloseNotification

对于 View ,您可以覆盖 -view[Will|Did]MoveTo[Window|Superview][:]

如果您确实响应此类通知或方法调用并进行不可逆的清理,请务必清除相关属性,以免重复。例如,将委托(delegate)设置为nil、删除观察者等。

关于objective-c - 当标准 NSView 或 NSWindow 被破坏时,是否有可靠的方法来破坏私有(private)数据结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29522715/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com