Re: Multiple NSTableView question
Re: Multiple NSTableView question
- Subject: Re: Multiple NSTableView question
- From: Greg Titus <email@hidden>
- Date: Thu, 21 Jun 2001 09:17:42 -0700
On Thursday, June 21, 2001, at 06:24 AM, Phillip Mills wrote:
On 6/20/01 10:31 PM, "Joe Schiwall" <email@hidden> wrote:
theTableView parameter is a pointer to one of the NSTableView Objects,
so
you can just compare the pointers to see which object it points to, for
example:
- (int)numberOfRowsInTableView:(NSTableView *)theTableView
{
if (theTableView == myTableView1)
do something;
else if (theTableView == myTableView2)
do something else;
}
Being new to Obj-C and Cocoa....
This seems very non-OOP and I wonder whether it's a normal Obj-C
idiom. (?)
I would have expected something like:
- (int)numberOfRowsInTableView:(NSTableView *)theTableView
{
[theTableView doSpecialStuff];
[self doCommonStuff];
}
But this, of course, requires extensions to NSTableView...sub-class,
category...? Using PowerPlant, I would have automatically considered
sub-classing (because it's really easy) if doSpecialStuff was at all
complex. Is polymorphism for UI classes abnormal here?
Yes, it is abnormal. Because you aren't changing how the table view
works at all, you are simply changing what data is displayed in it.
Therefore subclassing NSTableView is a bad idea because it binds what
should be controller logic directly into view code. You should only
subclass UI classes if you have different UI, and since the whole point
is to give the user a consistent user experience, that is relatively
rare. (Or at least _should_ be relatively rare.)
The question was explicitly: What do you do when you have two table
views hooked up to a single delegate to distinguish between the two
tables? The solution Joe gives above is the way you'd want to do it...
What you are driving at is a different question: What if I have two
table views with some of the data manipulation code in common and other
parts that are unique? That is, the view code (the UI of how a table
works) is the same, but the controller code (what data you interact
with / how) is different with some similarities. Put that way, the
obvious solution is to have two separate controllers, each subclasses of
a generic controller which does the common stuff. in Interface Builder
instantiate one of each controller subclass, and hook up the appropriate
table view to each controller.
@interface GenericController : NSObject
@end
@implementation GenericController
- (int)numberOfRowsInTableView:(NSTableView *)theTableView
{
[self doCommonStuff];
}
@end
@interface ControllerOne : GenericController
@end
@implementation ControllerOne
- (int)numberOfRowsInTableView:(NSTableView *)theTableView
{
// doSpecialStuffNumberOne...
[super numberOfRowsInTableView:theTableView];
}
@end
@interface ControllerTwo : GenericController
@end
@implementation ControllerTwo
- (int)numberOfRowsInTableView:(NSTableView *)theTableView
{
// doSpecialStuffNumberTwo...
[super numberOfRowsInTableView:theTableView];
}
@end
This is just as object-oriented as the way you describe, but this
example shows how the Model-View-Controller paradigm tends to emphasize
object composition more than inheritance. We have more but simpler
objects this way, which improves maintainability and readability. Not
mixing model with controller or controller with view also greatly
improves reusability of the various layers.
That having been said, making something more object oriented is supposed
to help you as a programmer get more done faster in a more maintainable
way. But it's a technique among many other techniques, not a religion.
The original pattern (a single controller with if statements comparing
which table we're talking to) can be more straightforward and easier to
understand if what you are doing differently with the tables is very
simple and/or the two tables share a lot of information in common so the
code to communicate it between two different controllers would be more
complicated than just having all the data handled in one place. So, like
with everything else, the best way to go is going to depend on the
specifics of your problem.
--Greg