Re: Repost: NSTableView headaches (please help!)
Re: Repost: NSTableView headaches (please help!)
- Subject: Re: Repost: NSTableView headaches (please help!)
- From: Karl Kraft <email@hidden>
- Date: Wed, 30 Jul 2003 22:17:05 -0500
On Wednesday, Jul 30, 2003, at 13:43 US/Central, Brad Peterson wrote:
[ itemList removeAllObjects ];
[ tableFiles setNeedsDisplay: YES];
[ tableFiles reloadData ];
[ tableFiles setNeedsDisplay: YES];
if (![newItemList count]){
[ self setBusy:NO];
return;
}
[itemList addObjectsFromArray: newItemList];
[ tableFiles reloadData ];
[ tableFiles scrollRowToVisible: 0 ];
When I added the setNeedsDisplay lines above, at first it seemed to
work, but again, not reliably. *sigh*
That's known as shotgun debugging. AIm in the general direction of
where you think the problem is, pull trigger, and hope the scatter
pattern gets it.
(Did I mention I'd inherited this code? ;) )
Not an excuse. :-) Code seldom works correctly the first time, and
the trick is knowing how to fix it. If you can't manage maintenance
programming then pass it off to someone who can.
Debugging code snippets is especially hard, because debugging is
usually requires a holistic approach.
If I was handed this code, and off the top of my head having heard
only the symptoms, I would look for the following things:
1) It sounds like the original developer didn't quite know what he was
doing. So he probably made lots of common coding mistakes that are now
coming back to bite you when you try to improve the code. So look for
those. For instance, does he have instance variables that require
synchronization. A classic example would be that he is stuffing the
count of the displayed list in the instance variable, and you aren't
updating it. Also look for any side effect code in methods like
setBusy: or any of the dataSource methods that are being called. Did
he use instance variables instead of method-scope variables in several
places, and is getting bit on those? In coding, style counts.
2) A pile of bad code is like a pile of dung. You can't make it
appetizing by adding filler. Instead start by removing things by
commenting them out. The code above is dung piled on top of dung. You
aren't getting anywhere with that strategy. Of particular dubious
parentage is a method that changes state of the obejct (setBusy:) in
the middle of a bunch of UI code. Code executes linearly, so in most
cases you should code that way.
3) Again, the problem is not where you think it is. Start with what is
not working versus what is working. How does a NSTableView draw?
Well, at the bottom of the event loop, the app walks through and lets
any view that needs to be updated get updated. So whether you call
setNeedsDisplay 1 time or 100 times, it is only going to display once.
(BTW guess what reloadData does for you? Read the docs) How does the
NSTableView know what to draw? Well it asks the dataSource for the
number of rows, and then iterates over them. In your case you
implied that resizing the window will make it draw correctly EVERY
time. So look for anything that changes between the first drawing and
the second.
3A - Are you throwing any exceptions in drawing code? This will often
result in the behaviour you indicated where in the middle of the
drawing the exception is thrown, the UI doesn't get updated, but
because of out of order calls the second attempt at drawing succeeds.
3B - If you do have a problem in drawing with an NSTableView, it is
going to be in the code that gets executed when the drawing occurs, not
in code that tells the NSTableView to schedule the drawing. Since
NSTableView is some serious time tested well deployed code, and works
in many other programs but not yours, the problem is probably in the
dataSource methods that get called by NSTableView, not in how you tell
the NSTableView to reload the data.
3B:1 - Do your data source methods have any side effects? Do they
work when called repeatedly? For instance, numberOfRowsInTableView: is
actually called more than once in the drawing loop. Is the code in
that method any more complex than return [itemList count] ? And even
if it is, set a debugger break point and see what the method is
returning each time. If you don't know how to use the debugger, than
NSLog the returned value.
3B:2 - The other dataSource method of note would be
tableView:objectValueForTableColumn:row:. Does this method work
correctly no matter what order it is called in? Again, setup the
debugger break points or NSLog commands and see when it is getting
called and what it returns.
3B:3 - Did you do anything funky? Do you have any object taking
notifications for the NSTableView? When you empty the table view it
may be posting notifications that the selection has changed. Set
breakpoints on every method of yours that may be called by NSTableView,
and see if and what order they are being called in.
3B:3(a) - Did you do something somewhere because it was easy even
though incorrect? For example, the dataSource methods both take an
NSTableView argument. That is so if you have one controller driving two
tableviews, you can distinguish which data set you should be returning.
However, some developers make the mistake of then turning around and
telling the table view in the numberOfRowsInTableView: to do something,
like set the background color, or set a new target, or change a column,
or heaven knows what else. DataSource and delegate methods should do
exactly what they are supposed to do and nothing else.
BTW - in all of the above you and your code refers to the author of the
code in the generic sense. It' just easier to write if I assume it's
all your fault. :-)
--
Karl Kraft
email@hidden
To purchase it is not like spending money
but rather it is an investment in the future
in a blow against the empire
_______________________________________________
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.