保留在回调中创建的窗口

时间:2017-09-05 21:25:28

标签: objective-c macos cocoa automatic-ref-counting

我想知道从回调中产生一堆窗口的正确方法是什么,基本上我想点击像 Ctrl + Shift + Cmd + + 并创建一个新窗口,该窗口未绑定到app delegate。目前,我的AppDelegate.m中包含以下代码:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
    NSLog(@"Finished");

    [NSEvent addGlobalMonitorForEventsMatchingMask:NSEventMaskKeyDown handler:^(NSEvent *event) {
        NSUInteger ctrlPressed  = [event modifierFlags] & NSEventModifierFlagControl;
        NSUInteger shiftPressed = [event modifierFlags] & NSEventModifierFlagShift;
        NSUInteger cmdPressed   = [event modifierFlags] & NSEventModifierFlagCommand;

        NSUInteger EqButton   = 0x30;

        if (ctrlPressed && shiftPressed && cmdPressed) {
            if ([event keyCode] & EqButton) {
                __strong ETTimerController *controller = [ETTimerController new];
                [controller showWindow: self];
            }
        }
    }];
}

这个片段创建了一个控制器和一个绑定的nib文件,但我无法看到窗口,我认为它是由ARC收集的。如何保留创建并保留新窗口而不在AppDelegate实例中存储引用?

1 个答案:

答案 0 :(得分:1)

不仅是窗口,而且我认为一旦块退出,窗口 controller 就会在这里发布。

将其存储在AppDelegate

的强大属性中
@property (nonatomic, strong) timerController *ETTimerController;

然后,像这样实例化它:

self.timerController = [ETTimerController new];
[self.timerController showWindow: self];

编辑:正如评论中所提到的,窗口控制器引用需要由某个持久对象拥有(或者是某个地方的静态变量),否则一旦该方法退出就会超出范围和ARC释放对象。 如果你在AppDelegate类中买不起专用属性(因为你需要有不同数量的不同窗口控制器等),那么你需要考虑每个控制器的预期生命周期,并相应地存储引用:

  • 如果你的窗口控制器重用,即它的窗口被重复显示和隐藏,但你最多只需要一个,使它成为 singleton 和静态对共享实例的引用将保留它。

  • 如果要构建document-based app,NSDocument子类的每个实例都将在makeWindowController()方法中创建其所有窗口控制器,并将它们保留在数组属性中。

  • 如果以上都不适用,您需要考虑其他因素 - 根据您的需求和规格而有所不同。