如何在打开和关闭窗口时重用NSWindowController的变量

时间:2014-02-13 07:32:54

标签: objective-c macos cocoa

目标:我想创建一个控制器类(最好是单例)来以编程方式管理打开和关闭NSWindows。当一个窗口关闭时,它应该被释放,因此它不会占用内存。一次只能有一个窗口。我没有使用nib文件。

为每个视图实例化一个新NSWindowController并使用它close方法关闭它似乎会导致内存问题(EXC_BAD_ACCESS)。

在此示例中,当通过计划的计时器重新打开窗口时,应用程序崩溃。

的AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
  self.controller = [[MyController alloc] init];
  [self.controller open];
  [self.controller close];
  [NSTimer scheduledTimerWithTimeInterval:1.0 target:self.controller selector:@selector(open:) userInfo:NULL repeats:false];
}

myController的

- (void) open:(NSTimer *) timer {
    [self open];
}
- (void) open {
    self.windowController = [[NSWindowController alloc]
                             initWithWindow: [[NSWindow alloc]
                                              initWithContentRect:NSMakeRect(30, 30, 300, 300)
                                              styleMask:NSTexturedBackgroundWindowMask
                                              backing:NSBackingStoreBuffered
                                              defer:false]];
    [[self.windowController window] setReleasedWhenClosed:true];
    [[self.windowController window] orderFrontRegardless];
}
- (void) close {
    [self.windowController close];
}

显然,这感觉就像一个糟糕的方法。什么是更好的设计来实现目标?

1 个答案:

答案 0 :(得分:0)

我不确定你是否在其他任何地方引用了self.windowController,但为了安全起见你应该:

- (void) close {
    [self.windowController close];
    self.windowController = nil;
}

所以你不要在窗户被释放后不小心碰到窗户。

另外,作为一种风格问题,不要使用这样的一次性定时器,只需使用-perform:withObject:afterDelay:

最后,当您考虑创建一个单独的类只是为了控制另一个类的实例时,请考虑在子类上创建这些方法类方法。比如,您可以使用NSWindowController+open方法编写自己的+close课程。