我是 Mac 开发新手。我来自 iPhone 开发人员。
我的问题涉及非模式窗口管理。它与iPhone及其内存管理模型有很大不同。
举例来说,我有一个首选项窗口,我可以使用类似的东西来显示该窗口:
-(IBAction)showPreferenceController:(id)sender {
if (!preferenceController) {
preferenceController = [[PreferenceController alloc]init];
}
[preferenceController showWindow:preferenceController];
}
但使用此代码,该窗口将在应用程序生命周期中保留在内存中,因为该窗口永远不会被释放。
为了避免这种情况,我还可以使用此处描述的方法:
stackoverflow.com/questions/1391260/who-owns-an-nswindowcontroller-in-standard-practice
创建于PreferenceController
a + (id) sharedInstance
并使用释放窗口(void)windowWillClose:(NSNotification *)notification
我看到许多可可代码示例,其中非模式窗口从未被释放。
例如这里:http://www.mattballdesign.com/blog/2008/10/01/building-a-preferences-window/ http://www.mattballdesign.com/blog/2008/10/01/building-a-preferences-window/:首选项面板和所有子视图均在中创建awakeFromNib
因此在应用程序的整个生命周期中都将存在于内存中。
如果以 Xcode 应用程序为例,有很多非模式窗口:
- 全局查找窗口(CMD+MAJ+F)
- 应用程序信息面板
- 帮助窗口
- ...
我认为这些窗口在关闭时会被释放,以保持尽可能低的内存。
我想要一些建议来了解在可可应用程序中管理非模式窗口的最佳方法。
保留在记忆中吗?尽快释放?
我知道与 iPhone 相比,Mac 拥有大量内存,但我也认为保留我们不使用的内存对象并不好。
Thanks.
与 Rob 帖子一起编辑 :
我将 -autorelease 发送到窗口并将指针设置为 nil,以便稍后重新创建窗口。这与您引用的技术类似,尽管是否为控制器使用 +sharedController 并不相关;无论您是否有共享控制器,您都可以执行此操作。
如果没有单例(+sharedController),我不知道如何做到这一点。
我用这个例子解释我的意思:
在应用程序控制器中:
@interface AppController : NSObject <NSApplicationDelegate> {
执行 :
-(IBAction)showPreferenceController:(id)sender {
if (!preferenceController) {
preferenceController = [[PreferenceController alloc]init];
}
[preferenceController showWindow:preferenceController];
}
在首选项控制器中:
@interface PreferenceController : NSWindowController <NSWindowDelegate>
执行 :
- (void)windowWillClose:(NSNotification *)notification {
[self autorelease];self=nil;
}
当我关闭窗口并在窗口后重新打开时,它会崩溃:preferenceController被释放但不等于nil。所以我需要在窗口关闭时将preferenceController设置为nil。
对于单例来说这样做没有问题。
如果没有单例,我应该将 appController 设置为首选项窗口的委托,以便能够在窗口关闭时将首选项控制器设置为 nil。但我不喜欢这样。
编辑普雷斯顿评论
我没有这么说,但我只想要我的非模态窗口的一个实例,即使我们调用-(IBAction)showPreferenceController:(id)sender
几次。
这就是为什么我测试appController中的preferenceController是否等于nil。
因此,如果我们关闭窗口,我需要在 appController 中将preferenceController 设置为 nil。
所以解决方案是:
在应用程序控制器中,监听 NSWindowWillCloseNotification:
- (void)windowWillClose:(NSNotification *)notification {
if ([notification object] == [preferenceController window]) {
[preferenceController autorelease];
preferenceController = nil;
}
}
这是对的吗?这是唯一的解决方案吗?因为管理我的非模态窗口似乎有点复杂......