谁拥有NSWindowController,在标准做法?

BJ *_*mer 12 cocoa objective-c

在看到负责释放NSWindowController对象后,我正在寻求进一步的澄清

我正在为我的侄子写一个简单的库存管理应用程序.我有一个表格视图,显示其"库"等的内容.要向库中添加新项目,他们会单击"+"按钮.此按钮将打开一个新窗口,提示他们输入项目的详细信息,并在单击"确定"时验证输入.

所有这一切都很好.但是,我对内存管理有疑问.要创建新窗口,我使用以下代码:

- (IBAction)addNewItem:(id)sender {
  LibraryItemEditorController *editorController = 
    [[LibraryItemEditorController alloc] 
          initWithWindowNibName:@"LibraryItemEditor"];

  [editorController showWindow:nil];
  // editorController is "leaked" here, it seems.
}
Run Code Online (Sandbox Code Playgroud)

我不能editorController在最后发布(也不自动发布)addNewItem:,因为没有别的东西在引用editorController; 如果我释放它,窗口会立即消失.但是,我希望窗口控制器在窗口关闭后释放.在Apple的Window Programming Guide中,我阅读了以下内容:

如果你想关闭一个窗口使窗口和窗口控制器在它不是文档的一部分时消失,你的子类 NSWindowController可以观察 NSWindowWillCloseNotification或作为窗口委托实现该 windowWillClose:方法并在下面包含以下代码行:你的实施:

[self autorelease];
Run Code Online (Sandbox Code Playgroud)

我用过窗口控制器[self autorelease]windowWillClose:方法.这样做,并且不会泄漏内存.然而,它只是感觉丑陋; addNewItem:看起来它正在泄漏记忆,而静态分析也是如此. 知道它实际上是在照顾windowDidClose:,但它只是感觉不对.此外,窗口控制器现在正在释放自身,而没有保留自己.这一切都违背了我所学到的内存管理规则.

我的另一个选择是把父控制器(可以是伊娃NSWindowControllerNSMutableSetNSWindowController多个),然后查看该NSWindowWillCloseNotification父控制器和响应释放.这更清洁,可能就是我要做的.不过,这也是一项相当多的工作,这引出了我的问题.

正在注意NSWindowDidCloseNotification这样做的标准方式吗?NSWindowControllers根据需要创建和销毁的标准管理方法是什么?这是[self autorelease]传统推荐选项的方式,现在我们只有静态分析这是一个问题吗?

Dar*_*ren 5

听起来你的窗户是模态的,在这种情况下:

[NSApp runModalForWindow:[editorController window]];
[editorController release];
Run Code Online (Sandbox Code Playgroud)

这是非模态窗口的一种模式:

@implementation QLPrefWindowController

+ (id) sharedInstance
{
    if (!_sharedInstance)
    {
        _sharedInstance = [[QLPrefWindowController alloc] init];
    }
    return _sharedInstance;
}

- (void)windowWillClose:(NSNotification *)notification
{
    if ([notification object] == [self window] && self == _sharedInstance)
    {
        _sharedInstance = nil;
        [self release];
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,任何想要访问或显示窗口的人都可以通过+sharedInstance类方法完成.如果窗口不可见,则创建它,否则它们将获得当前可见的窗口.