0
votes

Goal: I want to create a controller class (preferably singleton) to programmatically manage opening and closing NSWindows. When a window is closed it should be released so it does not take up memory. Only one window is available at a time. I'm not using nib-files.

Instantiating a new NSWindowController for each view and using it's close method close it appear to cause memory issues (EXC_BAD_ACCESS).

In this example, the app crashes when re-opening the window via the scheduled timer.

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];
}

Clearly this feels like a bad approach. What would be a better design to achieve the goal?

1

1 Answers

0
votes

I’m not sure if you refer to self.windowController anywhere else, but as a matter of safety you should have:

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

So you don’t accidentally touch the window after it’s been released.

Also, as a matter of style, don’t use one-shot timers like that, just use -perform:withObject:afterDelay:

Finally, when you think about creating a singleton class just to control instances of another class, think about making those methods class methods on a subclass, instead. Like, you could write your own NSWindowController class with +open and +close methods.