Re: Distinct action messages from matrix of NSButtonCells
Re: Distinct action messages from matrix of NSButtonCells
- Subject: Re: Distinct action messages from matrix of NSButtonCells
- From: Brian Hill <email@hidden>
- Date: Wed, 3 Oct 2001 15:21:57 -0500
On Wednesday, October 3, 2001, at 03:09 PM, Erik M. Buck wrote:
From: "Brian Hill" <email@hidden>
- (void)myMatrixAction:(id)sender
{
switch([[sender selectedCell]tag])
{
case 0:
file://cell with tag 0 was clicked
break
case 1:
file://cell with tag 1 was clicked
break;
}
}
YUCK! Don't use a switch statement when polymorphism is available. The
switch statement will have to be changed every time the matrix cells are
re-ordered or new ones are added. The switch statement is very
fragile. It
localizes code inappropriately. It requires information that should be
encapsulated elsewhere such as the number and order of cells.
In my experience, re-ordering the cells in a matrix does NOT change the
cell tags that have been set in Interface Builder. There is no
requirement that the cell tag have any relationship to the order OR the
number of cells. I routinely give button cells tags like '-1000' to use
as return codes to close sheets, for example (ie.,
endSheetWithTagFromSender:). The cell tag != the index of the cell.
The Cocoa/Interface Builder paradigm requires that some amount of
interface information be kept somewhere other than the source code file
anyway (ie., the Nib file). Granted, a cell tag is qualitatively
different (somewhat) than an action message or a nib outlet.
As a general rule, when programming in Objective-C, if you are inclined
to
use a switch statement then your design is broken.
Instead of the switch statement, give each cell in the matrix its own
action
and ignore the tags. If you still want a central action to be called
when
any cell is clicked, write it like this:
- (void)myMatrixAction:(id)sender
{
id selectedCell = nil;
if([sender respondsToSelector:@selector(selectedCell)]) {
selectedCell = [sender selectedCell];
} else {
selectedCell = sender;
}
[[selectedCell target] performSelector:[selectedCell action]
withObject:selecetedCell];
}
The above code works if sender is the matrix or if sender is a cell.
The
above code works if cells are rearranged, added or removed. If
inappropriate recursion is encountered with the above code, just
surround
the code with a semaphore.
Yes, I have often written action methods that look very much like the
one you've written above, but please keep in mind that I was trying to
illustrate a simple concept in a simple manner.
Brian
email@hidden
http://personalpages.tds.net/~brian_hill
___________________________________________________________
"Why? I came into this game for adventure - go anywhere, travel
light, get in, get out, wherever there's trouble, a man alone.
Now they've got the whole country sectioned off and you can't
move without a form. I'm the last of a breed."
-- Archibald "Harry" Tuttle, Rogue HVAC Repairman
___________________________________________________________