FROM : Ken Thomases
DATE : Sun Jan 20 11:45:15 2008
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
DATE : Sun Jan 20 11:45:15 2008
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
| Related mails | Author | Date |
|---|---|---|
| Daniel Child | Jan 13, 17:59 | |
| mmalc crawford | Jan 13, 19:35 | |
| mmalc crawford | Jan 13, 20:24 | |
| Daniel Child | Jan 18, 21:09 | |
| Ken Thomases | Jan 20, 11:45 | |
| mmalc crawford | Jan 20, 11:58 | |
| Ken Thomases | Jan 20, 14:21 | |
| Daniel Child | Jan 21, 05:57 |






Cocoa mail archive

