【问题标题】:Custom Modal Window with Block Completion Handler带有块完成处理程序的自定义模式窗口
【发布时间】:2010-01-26 20:08:49
【问题描述】:

我被困住了!

我正在尝试创建自定义模式对话框。我希望它使用块作为完成处理程序来执行类似于 NSSavePanel 的操作。

我只复制了我认为需要的重要sn-ps。

@implementation ModalWindowController
    - (void)makeKeyAndOrderFront:(id)sender
                   modalToWindow:(NSWindow*)window
                      sourceRect:(NSRect)rect
               completionHandler:(void (^)(NSInteger result))handler {

        _handler = [handler retain];

        session = [NSApp beginModalSessionForWindow:[self window]];
        [[NSApplication sharedApplication] runModalSession:session];

        [[self window] makeKeyAndOrderFrontCentered:self expandingFromFrame:rect];
    }
    - (IBAction)okButtonPressed:(id)sender {
        [[self window] orderOut:self];
        _handler(NSOKButton);
        [NSApp endModalSession:session];
    }

@end

现在我可以使用代码调用它了:

[self.modalWindowController makeKeyAndOrderFront:self
                                   modalToWindow:[[self view] window]
                                      sourceRect:sr
                               completionHandler:^(NSInteger result) {
    NSLog(@"Inside Block");
    if ( result == NSOKButton ) {
        // do something interesting here
    }
}];
NSLog(@"Errg");

然而一切顺利,在方法 makeKeyAndOrderFront:modalToWindow:sourceRect:completionHandler: 完成后它不会阻塞线程,因此即使用户没有选择“ok”或“cancel”也会打印“Errg”。此时会显示模态窗口,用户单击“确定”,然后执行 _handler 块。但是,如果我尝试访问块中的局部变量,并且应用程序崩溃,因为一切都已经清理完毕。

从 makeKeyAndOrderFront:... 方法阻塞主线程的最佳方法是什么?这是使用块实现完成处理程序的正确方法吗?

【问题讨论】:

    标签: objective-c cocoa modal-dialog objective-c-blocks


    【解决方案1】:

    你的线路

    _handler=[handler retain];
    

    应该是

    _handler=[handler copy];
    

    这应该可以解决您的问题,即在调用完成处理程序之前局部变量已经消失。 [handler copy] 负责处理块中引用的局部变量,因此即使在程序流程退出您创建块的方法之后,局部变量也不会消失。

    记住以下事实:

    1. 块实例捕获块内引用的局部变量。
    2. 但是,块实例在堆栈上。当程序的流程超出您创建块的范围{...} 时,即使您保留它,它也会消失。
    3. 所以,如果你想在以后使用数据,你需要copy 它,而不仅仅是retain 它,就像你在这里所做的那样。 Copy自动retains 从块中引用的所有局部对象变量。
    4. 完成后,您需要release。它为块本身释放内存,并将release 消息发送到引用的本地对象变量。不过,如果您使用 GC,则不必关心这一点。

    要了解该区块的更多细节,我发现 Mike Ash 的文章 here 非常有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-30
      • 1970-01-01
      • 2021-03-29
      相关资源
      最近更新 更多