Re: Simple NSTableView Question - Newbie
Re: Simple NSTableView Question - Newbie
- Subject: Re: Simple NSTableView Question - Newbie
- From: Thomas Lachand-Robert <email@hidden>
- Date: Wed, 15 May 2002 23:07:31 +0200
Le mercredi 15 mai 2002, ` 09:29 , Michael George a icrit :
And what's the controller? Its role is to tranmit changes requested by
the user from the view (where the user interacts) to the data, and
eventually the other way if the data change by themselves (when you
receive new emails).
Yes, and this is my question. What *is* the controller? It seems that
NSTableView is a View with a handle to the Model (dataSource), with which
it interacts. Where does the model come into play in this scenario?
Probably you mean the controller. It's the glue between the others. The
model handles the information, but doesn't display it, except on request.
IT IS THE ONLY ONE ALLOWED to change it. It has methods like that:
-giveMeInformationAbout:(id)something; // called by everyone wants it
-addNewInformation:(i)newinfo; // called only by other model objects and
controllers.
The view displays the info, but doesn't change it. It has methods like
this:
-showThisInfo:(id)x atThisPosition:(NSPoint)p aboutThat:(id)y;
-changeColorOfDisplay...
and it asks the info it has to display, if needed, to the controller or
the model.
The controller handles the links in between. It does every interaction
that the model or the view cannot do alone. It is more useful when there
is more than a view and more than a model (which is usually the case).
Let me give a more specific example, still with Apple Mail. Here you have:
- models, one for each mailbox, containing the list of messages in the
mailbox; they are able to give information on every message (author, title,
etc.), the number of messages, ...
- views; the most important one being the table view for the list of
messages, but there is also a view for messages's content, for the list of
mailboxes, etc.
- one or more controllers.
Now assume that the user click on a message in the list.
1/ The table view tells the controller (it's usually its delegate): "user
clicked at row number 5";
2/ the controller computes that this table view + row number 5 means: the
5th message in mailbox "aaa" ordered by date, because it already knows
(from previous actions) that the current mailbox is "aaa" and the current
order is "by date".
3/ it asks the model "aaa": what is the 5th message in date order (the
messages may be stored in a very different order in the model);
4/ the model answers a handle to the message (probably just a number, say
44);
5/ the controller tells the view for message content: "display message
content 44 of maibox aaa";
6/ the view asks mailbox aaa (or the controller): "what is the content of
message 44 inside you?"
7/ the model answers and the view display that content.
Another example (all of these are fictitious, and you can consider a
number of variations here; just to give you the mechanism): say the user
click on the column header "subject":
1/ the table view tells the controller: the user clicked my second column;
2/ the controller gets the the column header, which is "subject" and
notice that's a different order;
3/ it asks the model: can you sort by "subject", the model answers yes;
4/ the controller tells the table view to reload all data;
5/ the table view asks data to its data source, which can be the
controller or the model object. Note that there is a design choice here,
because the data source must know the current sort criterion, which is not
a true data. So probably the controller is a better data source for that,
it just asks the model for the information in the adequate order.
The flow of information usually goes that way, from the user to the model.
But it can go the other way. So you received new mail:
1/ the model object taking new mails tells the model object for mailbox
"aaa": you got a new message, here it is; the mailbox adds this message to
this list;
2/ the mailbox could tell the controller, but it's better to completely
separate the model from every other objects (that makes them much more
reusable). So it just POST A NOTIFICATION telling to whose who like to
know: "hey, I mailbox aaa received new messages".
3/ now the controller knows that the currently displayed mailbox is aaa,
so it registered itself as a listener (see NSNotification...) for any
notification from this model object. So it hears the news...
4/ ...and tell to the table view, "reload everything" (note that the table
view doesn't even know that somethign interesting did happen, and doesn't
care).
Undeerstanding this helps a lot for dealing with all these NS***View in
AppKit.
I do not mean to sound argumentative, I'm just trying to grasp what would
be the best way to have a button on my window which will tell the Model
to add a row. That I have done. However, the Model needs to know from
the View where to insert the new row. But there is no handle from the
Model to the View to get this information.
No the model doesn't need to know. Try to make your design so that every
model object works alone, with no direct interaction with the controller
or the views. Here is a good way to enforce that: for every model class,
ensure that it #import Foundation (and possibly some other models headers)
BUT NOT AppKit (that's exactly what PB does for you when you create a new
Objective-C class, if not a subclass of some AppKit class). Use
notifications to tell the world about change in the models. Use
controllers to listen to the notifications, and send appropriate orders to
the views. Read Bill Cheeseman's Vermont recipes (at stepwise) to find the
way to do that properly.
Now the 1000$ question: WHY? why even bother to follow these rules? Here
it is:
1/ you will be able to copy your model objects to some other apps in the
future with no changes whatsoever (if they are used for the same modelling!
); you can even use them for an app with no UI or a command-line tool;
2/ you will reuse also your custom designed views, if you have some (most
of your views are probably coming directly from AppKit, through IB; try to
not subclass any view if you are a beginner);
3/ you will not be able to reuse the controllers, because they contain the
logic in the interaction between the data and the interface; but that's
only a relatively small part of your app;
4/ you can change the UI easily, if some user tells you: "it would be
better to have a popup menu here instead of a list of radio buttons" or
worse: "I would like to be able to change the color of that thing from the
menu also"... that's all changes in the controllers, not in the data nor
in the views (except you add some views and remove some eventually, in IB)
.
Nothing forces you to fllow the MVC paradigm. But it will make you MUCH
more efficient, believe me.
Thomas Lachand-Robert
********************** email@hidden
<< Et le chemin est long du projet ` la chose. >> Molihre, Tartuffe.
_______________________________________________
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.