Re: beyond MV and (one) C
Re: beyond MV and (one) C
- Subject: Re: beyond MV and (one) C
- From: Ken Thomases <email@hidden>
- Date: Sun, 20 Jan 2008 04:45:15 -0600
On Jan 18, 2008, at 2:09 PM, Daniel Child wrote:
On Jan 13, 2008, at 1:35 PM, mmalc crawford wrote:
Additional controllers come into play if you want to devolve
responsibility for managing a fairly self-contained subset of the
UI to a separate controller. NSWindowController is perhaps the
"biggest granularity" example where rather than an NSDocument
instance being responsible for multiple windows it can devolve
responsibility to individual window controllers. A window
controller might then devolve responsibility for managing, say, a
table view to an NSArray controller. Or for a custom view you
might implement your own NSViewController. It's all up to you to
decide how you want to factor out the workload.
I think I understand why you might devolve responsibility to window
controllers in a doc app. I don't see what they do in a non-doc app,
however.
More importantly, how you get the window controllers working in the
first place? The description of controller objects "owning"
mediating controllers (in "MVC Design Patterns") is totally
abstract to me until I see an example of how this is done.
To test the idea, I created an app with two nibs:
MainMenu.nib -- contains WindowA and WindowB
WindowC.nib -- contains WindowC
Each window has a button to reference the other two. (Open Window A,
Open Window B, etc.)
MainMenu.nib has an instance of a (typical) Controller (subclass of
NSObject) that has code for windows A and B.
WindowC.nib has an instance of a WindowCController that is a
subclass of NSWindowController, and has code for the actions of
Window C (openA and openB).
The nib should not contain an instance of a NSWindowController-derived
class. An NSWindowController is intended to be the owner of the nib.
As such, it's outside of the nib -- "above" it, in a certain sense.
So, when it comes time to load WindowC.nib, you do:
WindowCController* myWindowCController = [[WindowCController alloc]
initWithWindowNibName:@"WindowC"];
In the nib, you would set the class of File's Owner to
WindowCController. You'd also connect its "window" outlet to the
window in the nib. Then, anywhere that some other part of the code
needs to refer to WindowC, you use this expression:
[myWindowCController window]
If you want the WindowCController instance to know about the other
windows, you can add some ivars to it and set them up. You can do
that immediately after the alloc-init statement, above, or actually
define your own custom init... method that takes additional arguments.
One thing that might be confusing you: you might want a controller
which manages the window controllers. Often, there's an application
controller, which might also be the application delegate. This
application controller is what knows about the various nibs and window
controller classes. So, it is what would allocate and initialize the
WindowCController instance, as illustrated above except that
myWindowCController would not be a local variable, it would be an
instance variable. The application controller would also have the
"global" overview sufficient to connect the various nibs and window
controllers to each other.
Also, how will the different nibs know about each other? When I
instantiate the WindowCController, there seems to be no recognition
of the fact that I had declared an IBOutlet NSWindow *windowC or
IBActions (openA, openB). In other words, the instantiated subclass
of NSWindowController does not behave like a regular controller in
terms of the target-action paradigm.
I'm not sure I followed this part. What does "a regular controller in
terms of the target-action paradigm" mean?
Remember that you can target actions to the First Responder, as well
as a customer controller instance in the nib. And, if you do that,
then the application delegate is automatically included in the
responder chain that will be asked to handle the action. See <http://developer.apple.com/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/chapter_2_section_6.html#//apple_ref/doc/uid/10000060i-CH3-SW9
>. So, you can put the openA, openB, and openC methods in the
application delegate and any of your buttons will be able to invoke
them.
It's also perfectly acceptable to target the actions to the File's
Owner, which would be your custom subclass of NSWindowController. If
you're worried about duplicate code appearing in all of your
controller subclasses, figure out where the responsibility truly
should live, put it there, and just have the window controllers
forward the request. In other words, WindowCController could have an
openA: action method which just forwards the request to some method of
the application controller.
How does a WindowCController get a pointer to the application
controller? Well, it could be given one explicitly by the application
controller when it creates the WindowCController instance. Or, the
WindowCController can just use [NSApp delegate].
-Ken
_______________________________________________
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