Re: Modal Sheet without Spaghetti?
Re: Modal Sheet without Spaghetti?
- Subject: Re: Modal Sheet without Spaghetti?
- From: Michael Ash <email@hidden>
- Date: Tue, 27 Jan 2009 22:42:51 -0500
On Tue, Jan 27, 2009 at 8:10 PM, Jerry Krinock <email@hidden> wrote:
> I often find myself in the quandary where the innermost of some nested
> methods may run into a problem that requires a user decision before
> processing can continue. So I use a modal dialog in there, blocking the
> main thread, and everything works fine.
>
> Butt if the possible problem involves a document, I believe it would be a
> better user experience to use a sheet instead of a dialog. But, arghhh, the
> method
> -[NSApp
> beginSheet:modalForWindow:modalDelegate:didEndSelector:contextInfo:]
> returns immediately, sending its return message to a modal delegate
> selector. So I must go back up the nest, all the way up to the event which
> drove the process, and split all these methods into two methods, the code
> "before" and "after" the sheet runs. Repeat this for all other possible
> entry points into this innermost method. And there goes another afternoon.
>
> I believe the reason the reason why -[NSApp beginSheet:::::] returns
> immediately is that one would not want a document-modal dialog to block the
> main thread, preventing the app from doing other stuff.
>
> Does anyone have an idiom or way of appreciating this problem which does not
> produce such spaghetti and headaches?
Well as you note, this is to some extent an inherent limitation of the
API. Sheets are expressly designed to let the app keep running while
they're visible, so you're stuck dealing with asynchronous state.
But it can be made easier or harder depending on how you do it, of
course. I'd suggest that if you're asking the user for a decision from
code that's three layers deep, and which other code depends on for an
answer, then it may be indicative of a general design flaw.
If you can, try to arrange sheet code so that it either looks like this:
-topLevelMethod {
[self a];
[self b];
// show sheet
}
-sheetDidEnd {
[self cWithSheetAnswer:...];
}
So that the top-level method is the one driving things, or like this:
-topLevelMethod {
[self a];
}
-a {
[self b];
}
-b {
// show sheet
}
-sheetDidEnd {
[self cWithSheetAnswer:...];
}
So that the method that shows the sheet is fire-and-forget.
Additionally, if your code is well modularized, then your methods will
hopefully already be split up, so that when it comes to moving the
post-sheet stuff into separate methods, the work is largely done
already.
Mike
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden