块完成处理程序的自定义模态窗口 [英] Custom Modal Window with Block Completion Handler

查看:219
本文介绍了块完成处理程序的自定义模态窗口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我卡住了!

我试图创建一个自定义模态对话框。我希望它执行类似于NSSavePanel使用块作为完成处理程序。

I am trying to create a custom modal dialog. I would like it to perform similarly to the NSSavePanel using a block as a completion handler.

我只复制了我认为需要的重要代码段。

I've copied only the important snippets I think are needed.

@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:阻塞线程,因此即使用户没有选择确定或取消也将打印Errg。此时将显示模态窗口,其中用户单击确定,然后执行_handler块。但是,如果我试图访问块中的局部变量,应用程序崩溃,因为一切都已经清理。

All goes well however, after the method makeKeyAndOrderFront:modalToWindow:sourceRect:completionHandler: has completed it does not block the thread, so "Errg" will be printed even though the user has not selected "ok" or "cancel". The modal window is displayed at this point, where the user clicks OK and the _handler block is then executed. However if I am trying to access local variables in the block, and the app crashes as everything has cleaned up already.

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

What is the best approach to blocking the main thread from the makeKeyAndOrderFront:... method? Is this the right approach to implementing a completion handler using blocks?

推荐答案

您的行

_handler=[handler retain];

应为

_handler=[handler copy];

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

That should solve your problem, that the local variables are gone before the completion handler is called. [handler copy] takes care of the local variables referred to in the block, so that the local variables don't go away even after the flow of the program exited the method where you made the block.

请记住以下事实:


  1. 块实例捕获块内引用的局部变量。

  2. 但是,块实例位于堆栈上。当程序流程超出范围 {...} 时,即使您保留它也会消失。

  3. 所以,你需要 copy ,而不只是 retain 数据后,你在这里做。 自动复制自动保留所有从块中引用的局部对象变量。

  4. 完成后,您需要发布。它释放块本身的内存,并将 release 消息发送到引用的本地对象变量。

  1. The block instance captures the local variables referred inside the block.
  2. However, the block instance is on the stack. It will go away even you retain it, when the flow of the program go out of the scope {...} in which you create the block.
  3. So, you need to copy it, not just retain it, if you want to use the data afterwards, as you are doing here. Copying it automatically retains all the local object variables referred to from the block.
  4. You need to release it once you're done with it. It deallocates the memory for the block itself, and sends release message to the local object variables referred to. If you use GC, you don't have to care about this, though.

为了理解这个区块的更多细节,我发现该文章此处作者Mike Ash非常有帮助。

To understand more details of the block, I found the article here by Mike Ash very helpful.

这篇关于块完成处理程序的自定义模态窗口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆