从完成块开始时,模态 NSSavePanel 在动画化后消失

Modal NSSavePanel disappears after animating in when begun from a completion block

你好!

注意: 下面链接的最小示例。我将避免冗长的代码摘录,而是简明扼要地解释问题。

我正在将旧的(但很小的)Cocoa 应用程序更新到当前的 APIs。

起初看起来很简单的地方之一:当用户尝试关闭应用程序 window 并更改未保存时,应用程序首先显示 NSAlert 询问“保存你的东西?” .如果确认,将显示模态 NSSavePanel。在原始代码中,它们分别通过以下方式打开:

beginSheetModalForWindow:modalDelegate:didEndSelector:contextInfo:
beginSheetForDirectory:file:modalForWindow:modalDelegate:didEndSelector:contextInfo:

当前 Cocoa API 使用完成块,因此警报更喜欢通过 beginSheetModalForWindow:completionHandler: 显示。所以我将代码从 didEndSelector 移到了 completionHandler 中。

不幸的是,模态 NSSavePanel 确实有动画,但如果它从 NSAlert 的完成块window 中显示,它会立即与应用程序主 window 一起消失。如果我将警报切换回 didEndSelector,我可以显示 NSSavePanel 基于选择器或完成块就可以了。

Here's the NSAlert's completion block that forwards to the disappearing save panel.

我考虑过线程问题。所有这些都发生在主线程上。也许我遗漏了 运行 循环模式的一些微妙之处?

最小示例在 on GitHub 上可用。您可以使用 AppDelegate.h 中的定义在选择器和块之间切换。所有有趣的代码都在 AppDelegate.m 中。 (除非问题出在其他地方...)

正如@Willeke 所指出的,这并不是关于线程和诸如此类的问题过于神秘。不,只是我这些天看代码的次数太多了。

解决方法很简单:

The breaks in the switch statement in confirmUnsavedChanges are missing.