Re: The more I read about MVC, the more confused I get...
Re: The more I read about MVC, the more confused I get...
- Subject: Re: The more I read about MVC, the more confused I get...
- From: Brent Gulanowski <email@hidden>
- Date: Thu, 12 Jun 2003 22:01:50 -0400
On Thursday, June 12, 2003, at 05:54 PM, Koen van der Drift wrote:
Hi,
Although I do understand the concepts of MVC, using it with Cocoa still
somehow confuses me. I do know how to set up all the connections in
IB, and
how delegates, outlets and actions work, so that's not the problem.
It's
the actual coding part that confuses me, especially the
responsibilities
that classes should have and understanding how the model and the views
communicate with each other.
I don't know about you, but for me the difficulty comes from not always
knowing what methods get called when, but I think that's the reality of
using an application framework where an object you didn't design
(NSApp) is pulling the strings (plus the NSDocumentController instance
is hidden).
Usually the model does not communicate with the view at all. The model
might send notifications which are received by view classes, however.
My sense is that the controller classes respond to the view, and make
requests of the model, and vice versa. The controllers glue the other
parts together.
My app is a document based program with (so far) one main window. The
window contains a textview in which the user can edit a string that is
the
heart of the model. The window also contains a table view and some text
items that display the results of some calculations on the model, and
more
widgets to control the calculations.
I have read online articles, mailinglist discussions and tutorials, and
came to the conclusion that a 'model - modelcontroller -
viewcontroller -
view' setup fits my app the best.
The way I understand it, the following applies:
MyDocument: this is the 'modelcontroller' that owns the model, and is
responsible for opening/saving. It is a subclass of NSDocument.
MyModel: the model that does all the calculations.
MyMainWindowController: the viewcontroller that responds to user
actions in
the main window. A subclass of NSWindowController.
MyTextView, NSTableView, NSPopupButtons, etc: the views that form the
GUI.
sounds good so far.
Now suppose the user types in MyTextView to edit the model.
MyMainWindowController is the delegate and will get a notification.
Now how
do I pass this on to the model?
One possible way would be:
(void) textDidChange:(NSNotification *)aNotification
{
// pseudocode: get string from sender of notification
[[self document] setModelString:aString];
}
MyDocument can then pass the string to the model. Would this be
'recommended/best' way to do this?
If your model consists only of a single string (or attributed string),
you might not need to bother with the overhead of a custom window
controller. You can make the document the nib's owner and save yourself
a layer of communication. Another thing about strings is that they are
pretty transparent. The famous Cocoa no-code text editor has virtually
no controller class because the AppKit is so well versed in Strings. If
you had custom attributes or other parts in the string that would not
be reflected in the view, that would be a different story. In some
ways, the view is a model of the model, but only when it is necessary
to present the model in a different form than it exists in "naturally".
With strings, that would only be the difference between formatting and
drawing, but that's all AppKit friendly, so the abstraction is a bit
flimsy.
Another problem is understanding how the communication goes the other
way
around, from the model to the views
Again, suppose the model has changed after the user typed in
MyTextView and
the other views need to be updated accordingly. The data that some of
the
views display is derived from the model. However, the viewcontroller
does
not know about the model. But how do I get the data from the model
into the
different views?
One way I thought of is that MyDocument gets a notification from the
model
when something has changed or has been calculated. MyDocument can then
tell
MyMainWindowController to update all the views, and passes the model
as an
argument so the views can use accessors to get the updated data.
Is that a usable approach?
I think you have it just fine. But it doesn't have to be a notification
-- usually a controller itself requested the update and knows there was
a change. You can use that knowledge and have the model controller (the
document) immediately send either notifications or -update messages to
windows, or specific messages to views, which will usually result in
them requesting to have their contents re-freshed by whatever
controller is vending it to them.
But how does this work for the NSTableView? Can I set MyModel (which
provides an NSArray that is used to fill the table) to be the
datasource of
the NSTableView?
The message sent to table views (and outline views) is -reloadData. I
see we're getting more complex than just some single string.
Last question. My app also uses several NSDictionaries that are used to
setup the popup-buttons. The model uses data from the dictionary,
depending
on the selection in the popup-button the user made. Which class would
be
the most logical to own these NSDictionaries? At a later stage I want
to
implement user defined entries for the dictionaries.
Hrm, not sure I understand this one clearly. Unless you are filling the
pop-ups programmatically and dynamically, wouldn't it be better to just
set them up in IB? Otherwise, if the dictionaries aren't part of the
model, then a view controller should own them, I believe. The rest
would be standard target-action stuff. The view should be very stupid
about anything but itself. It is there to present controls, but it
doesn't know what those controls mean, only how to report that the user
has interacted with them, and what state they are in. The view
controller retrieves that state information, and passes it onto the
document in a format more suitable to the model. Then the document
updates the model, because it knows the details of the model's
interface.
For single-window apps, this division of the controller into two layers
can be considered optional. Even if you don't make custom window
controllers, the document controller will, but you don't have to know
they are there. Your controls and views can talk directly to the
document. Because controllers are mostly just collections of methods,
with little or no state, the locations of those methods is partly a
matter of being organized, although changes to the view will
necessitate changes to the view controller, so it is good to have it
de-coupled from the document logic.
Brent Gulanowski email@hidden
--
If you paid a million monkeys to type on a million keyboards,
eventually they would produce the collected works of William Gates III.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.