如何在垃圾收集的 Obj-C 中保留窗口而不保留指向它的指针?

发布于 2024-08-23 15:52:10 字数 321 浏览 11 评论 0原文

我目前正在学习 Aaron Hillegaas 所著的著名的“Cocoa Programming for OSX”。

在第 12 章中,他希望我创建一个“关于”窗口

[BOOL] successful = [NSBundle loadNibNamed:@"About" owner:self];

,使用该窗口本身效果非常好。但是,我正在使用垃圾收集器,并且由于我不保留指向窗口的指针,因此它被垃圾收集,因此在一两秒后消失。如果禁用垃圾收集,它会很好地工作。

有没有办法创建一个窗口而不持有指向它的指针并且不让它被垃圾收集器吃掉?

I am currently working through the famous "Cocoa Programming for OSX" by Aaron Hillegaas.

In Chapter 12 he wants me to create an about window using

[BOOL] successful = [NSBundle loadNibNamed:@"About" owner:self];

which, by itself, works perfectly well. However, I am using the garbage collector and since I do not retain a pointer to that about window, it is garbage collected and thus disappears after a second or two. It works perfectly well if garbage collection is disabled.

Is there a way to create a window without holding a pointer to it and without having it eaten by the garbage collector?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梨涡少年 2024-08-30 15:52:10

您可以 使用 CFRetain 保留窗口,或使用 NSGarbageCollectordisableCollectorForPointer:。但是,您很容易引入内存泄漏。确保用于关闭窗口的任何操作也会释放该窗口。

如果传递给关闭操作的 sender 继承自 NSView,它将有一个 window 属性您可以使用 来获取指向窗口的指针。

然而,这并不是 Cocoa 设计的工作方式。在 Hillegaas 的书第 12 章中,他这样说:

当第一次发送 showWindow: 时,NSWindowController 会自动加载 nib 文件并将窗口移动到屏幕上并移动到前面。 nib 文件仅加载一次。当用户关闭[窗口]时,它会移出屏幕,但不会释放。下次用户请求[窗口]时,它只是在屏幕上移动。

如果您取消分配“关于”窗口,您的应用程序将崩溃或在有人第二次打开它时似乎没有响应。

编辑:另一种方法(但不会让您练习加载笔尖)是将“关于”窗口和一个 NSWindowController 添加到主笔尖(确保取消选中“关于”窗口的“启动时可见”属性)。这会使 Main.nib 变得混乱,但完全可以在 Interface Builder 中完成。连接:

  • 将“关于”控制器的窗口出口连接到“关于”窗口
  • 将“关于”控制器的 showWindow: 操作连接到“关于”菜单项
  • 如果“关于”窗口中有自己的关闭按钮,请将其连接到窗口的 执行关闭: 操作。

至于本课程的建议程度,苹果有话要说

一个非常简单的应用程序可能能够将其所有用户界面组件存储在单个 nib 文件中,但对于大多数应用程序来说,最好将组件分布在多个 nib 文件中。创建较小的 nib 文件可以让您仅加载界面中您立即需要的部分。较小的 nib 文件可为应用程序带来更好的性能。它们还使您可以更轻松地调试可能遇到的任何问题,因为查找问题的位置较少。

You can retain the window with CFRetain, or use NSGarbageCollector's disableCollectorForPointer:. However, you can easily introduce a memory leak. Make sure whichever action you use to close the window also releases the window.

If the sender passed to the close action inherits from NSView, it will have a window property that you can use to get a pointer to the window.

However, this is not how Cocoa is designed to work. In Chapter 12 of Hillegaas' book, he has this to say:

When sent showWindow: for the first time, the NSWindowController automatically loads the nib file and moves the window on screen and to the front. The nib file is loaded only once. When the user closes the [window], it is moved off screen but is not deallocated. The next time the user asks for the [window], it is simply moved on screen.

If you deallocate the About window, your app will either crash or appear not to respond the second time someone opens it.

Edit: An alternative (but one that doesn't give you practice in loading nibs) is to add the About window an an NSWindowController to the main nib (make sure you uncheck the About window's "Visible At Launch" attribute). This makes a mess of Main.nib, but can be done entirely in Interface Builder. Connect:

  • the About controller's window outlet to the About window
  • the About controller's showWindow: action to the About menu item
  • if you've your own close button in the About window, connect it to the window's performClose: action.

As for how advisable this course is, Apple has this to say:

A very simple application might be able to store all of its user interface components in a single nib file, but for most applications, it is better to distribute components across multiple nib files. Creating smaller nib files lets you load only those portions of your interface that you need immediately. Smaller nib files results in better performance for your application. They also make it easier to debug any problems you might encounter, since there are fewer places to look for problems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文