Implementing sheets with beginSheet:completionHandler

Shane has mentioned in a couple of past threads that there is a bug that prevents using beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo with an actual didEndSelector argument. (All my attempts result in a crash due to EXC_BAD_ACCESS.)

Since beginSheet:modalForWindow… has been deprecated, I thought I’d try beginSheet:completionHandler. Even here, I get the same crash when specifying a completionHandler. Is this due to a bug as well, or am I doing something wrong? (It works fine if completionHandler is “missing value”.)

on clickShowSheet_(sender)
	tell theWindow to beginSheet_completionHandler_(theSheet, "endSheetCompletionHandler:")
end clickShowSheet_

on clickCloseSheet_(sender)
	set returnCode to current application's NSModalResponseOK
	tell theWindow to endSheet_returnCode_(theSheet, returnCode)
end clickCloseSheet_

on endSheetCompletionHandler_(returnCode)
	tell theSheet to orderOut_(me)
end endSheetCompletionHandler_


That doesn’t mean a handler in the AppleScript sense – it requires a block, which is essentially an inline function. You can’t use blocks in AppleScriptObjC.

You can get roughly the same functionality if you use my Myriad Helpers, the class categories of which use beginSheet:completionHandler:.

Makes sense, thanks.

Is it safe to say then that sheets work just fine in vanilla AppleScript as long as I don’t need a completion handler? I can live with that, it just means I have to remember to call endSheet() and orderOut() together, instead of being able to consolidate the orderOut() calls into a completion handler.

Which, looking at Myraid Helpers, I notice that orderOut() is called in a completion handler only when using showOver() with a timeout. I assume then that when using the showOver() without a timeout, I have to call orderOut() myself alongside endSheet()?

They work fine with the deprecated methods.

The rules differ when using a completionHandler: block.

I’ve had no issues (so far) with using the new beginSheet too as long as completionHandler is set to “missing value”.

So is calling orderOut not always necessary after endSheet? The documentation for NSAlert’s beginSheetModalForWindow explicitly mentions, “Note that orderOut: no longer needs to be called in the completion handler. If you don’t dismiss the alert, it will be done for you after the completion handler finishes.” But, I haven’t run across any other hints about when orderOut is necessary or not.

The documentation means what it says.

To be honest, I think worrying about this sort of deprecation is needless. There are degrees of deprecation, and the delegate methods have not been hard deprecated.

No worries from me. I’m mostly using the new beginSheet because it has fewer arguments :slight_smile: If the deprecated beginSheet provided any advantage, I’d be happy to use it instead. My conclusion, in short, is if you need sheet completion handlers, your Myriad Helpers provides the easiest way to get them. Thanks!