Re: Easy TableView problem
Re: Easy TableView problem
- Subject: Re: Easy TableView problem
- From: Ryan Bates <email@hidden>
- Date: Fri, 27 Feb 2004 11:11:59 -0800
On Feb 27, 2004, at 10:36 AM, Barrett M. Conrad wrote:
samples = [samples arrayByAddingObject: [[RISBVSample alloc]
initWithValues:[currentRow objectAtIndex:0]
<snip>
My retain and release skills are still a little weak. Should I be
paying better attention to that?
Yes, this is the problem. the "arrayByAddingObject:" method returns a
completely new array that is auto-released (notice no "alloc", or
"copy" in the method name). Which means, at the end of the run loop,
the array will be deallocated (if no other objects are retaining it)
and you can no longer access it.
For a quick fix, you can release the old array before setting a new one
then retain the new array, like this:
while (currentRow = [enumerator nextObject]) {
[samples release];
samples = [samples arrayByAddingObject: /* ... */];
[samples retain];
}
A much better way to handle this is with accessor methods which get and
set the instance variable. This way you don't have to worry about
retaining and releasing an instance variable when setting it. Here's
example accessor methods for the "samples" array.
- (void)setSamples:(NSArray *)newSamples
{
[samples autorelease];
samples = [newSamples retain];
}
- (NSArray *)samples
{
return samples;
}
In fact, this would be much better suited for an NSMutableArray object,
which allows you to add objects using an "addObject:" method which does
not return a new array - simply alters the current array. I suggest you
look into that.
Ryan
On Feb 27, 2004, at 10:36 AM, Barrett M. Conrad wrote:
Yeah that wasn't the best place to put that comment. The only other
code that I think is being called is the following:
-(id)init {
return [self initWithAllSamples];
}
-(id)initWithAllSamples{
samples = [[NSArray alloc] init];
dbconnection = [[RISBVDatabase alloc] initWithConnection];
[self getAllSamples];
return self;
}
-(void)getAllSamples {
NSArray *results;
NSEnumerator *enumerator;
id currentRow;
results = [dbconnection queryWithStringGetArray:@"SELECT * FROM
sample_tbl"];
enumerator = [results objectEnumerator];
while (currentRow = [enumerator nextObject]) {
samples = [samples arrayByAddingObject: [[RISBVSample alloc]
initWithValues:[currentRow objectAtIndex:0]
subjectID:[currentRow objectAtIndex:1]
projectID:[currentRow objectAtIndex:2]
date:[currentRow objectAtIndex:3]
time:[currentRow objectAtIndex:4]
methodID:[currentRow objectAtIndex:5]
amountleft:[currentRow objectAtIndex:6] ] ];
}
NSLog(@"collection size = %d\n", [samples count]);
}
// THE DATASOURCES HEADER FILE
@interface RISBVSampleCollection : NSObject {
RISBVDatabase *dbconnection;
NSArray *samples;
}
-(id)init;
-(id)initWithAllSamples;
-(void)getAllSamples;
-(int)numberOfRowsInTableView:(NSTableView *)tableView;
-(id)tableView:(NSTableView *)tableView
objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row;
// END HEADER FILE
This code along with everything from my previous posts is all of the
code from the entire data source class. The NSLog output from
"getAllSamples" only shows up once and outputs a two which is correct.
I have also verified that "init" and "initWithAllSample" are also
only called once.
My retain and release skills are still a little weak. Should I be
paying better attention to that?
Thanks again,
Barrett.
On Feb 27, 2004, at 11:52 AM, Ryan Bates wrote:
On Feb 27, 2004, at 9:04 AM, Barrett M. Conrad wrote:
theSample = [samples objectAtIndex:row]; // I originally had
these as a single line, but split them for testing purposes. This is
the line that crashes.
Sorry, I missed this comment when I sent my last reply. What I
thought is probably not the problem in this case. You can check if
the row goes out of bounds before calling the method, but this will
not solve your problem, only avoid the crash.
if (row < [samples count]) {
theSample = [samples objectAtIndex:row];
tblObject = [theSample getSmplDate];
}
Your array must be getting set somewhere else. Is there any other
code that is being called before this?
Ryan
On Feb 27, 2004, at 9:04 AM, Barrett M. Conrad wrote:
Hi all,
Ok. I've fought with this for a day and a half and have come up
with nothing. I'm trying to implement a Table View for the first
time.
Seems easy enough.
Here is the scenario. I have a data source class that contains an
array called "samples" of custom objects. The custom objects have an
attribute called "smplDate" that is returned by the method
"getSmplDate." My data source is initialized with two objects in its
"samples" array. The data source implements what I understand to be
the minimum two methods, "numberOfRowsInTableView" and
"tableView:objectValueForTableColumn:row", as follows:
-(int)numberOfRowsInTableView:(NSTableView *)tableView{
return [samples count];
}
-(id)tableView:(NSTableView *)tableView
objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row {
id theSample, tblObject;
if( [ [ tableColumn identifier ] intValue ] == 0) {
theSample = [samples objectAtIndex:row]; // I originally had
these as a single line, but split them for testing purposes. This is
the line that crashes.
tblObject = [theSample getSmplDate];
}
return tblObject;
}
I believe I have everything in Interface Builder setup correctly
because the above works to a point. When the program launches the
correct data is displayed in the Table View, but then it suddenly
crashes. It crashes the third time
"tableView:objectValueForTableColumn:row" is called. I'm assuming
the
first two times it is called it display the data in the table
correctly, but the third time is a redraw (For what reason, I do not
know. I guess that's just what Cocoa does. I'm not doing it
purposefully.).
Here's the funny part. When I run the debugger, everything looks
kosher, then suddenly, on the third call of
"tableView:objectValueForTableColumn:row" the "samples" array in my
data source seems to "disappear." The debugger says the array has
two
objects, which is right, then it spits out this: {(int)[$VAR count]}
objects, instead of "2 objects". Once it does this, the program
crashes.
I just can't seem to see the problem. I appreciate the help a great
deal.
Your Aspiring Mac Developer,
Barrett M. Conrad
email@hidden
_______________________________________________
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.
_______________________________________________
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.