0

G'day!

Note: Minimal example linked below. I'll refrain from longish code excerpts and rather explain the problem concisely.

I am in the process of updating an old (but small) Cocoa application to current APIs.

One of the places that looked easy enough at first: When the user tries to close the application window with unsaved changes, the app first displays an NSAlert asking "Save your stuff?". If that is confirmed a modal NSSavePanel is shown. In the original code they were opened via, respectively:

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

Current Cocoa API uses completion blocks and thus the alert prefers to be shown via beginSheetModalForWindow:completionHandler:. So I moved the code from the didEndSelector into the completionHandler.

Unfortunately the modal NSSavePanel does animate in but disappears immediately together with the application main window if it is shown from the NSAlert's completion block. If I switch the alert back to the didEndSelector I can show the NSSavePanel either selector-basedly or completion block-ly just fine.

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

I have thought about threading issues. All of this is happening on the main thread. Maybe there's something subtle going on with run loop modes that I'm missing?

The minimal example is available over on GitHub. You can switch between selectors and blocks with defines in AppDelegate.h. All the interesting code is in AppDelegate.m. (Unless the problem is somewhere else...)

2
  • 1
    The breaks in the switch in confirmUnsavedChanges are missing. Commented Aug 25, 2020 at 9:10
  • @Willeke Oh. My. God. I didn't even see that one thing I didn't plain copy from the old selector anymore. Transformed an if-else into a switch statement and broke things. 🤦‍♂️ Thanks. Apparently this is the answer. Please post it as such and I shall accept it. Commented Aug 25, 2020 at 9:44

1 Answer 1

0

As @Willeke pointed out this wasn't an overly mysterious issue with threading and whatnot. No. It was just me having looked at the code way too often over the course of days.

The solution is simple:

The breaks in the switch statement in confirmUnsavedChanges are missing.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.