• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Easy TableView problem
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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.


References: 
 >Easy TableView problem (From: "Barrett M. Conrad" <email@hidden>)
 >Re: Easy TableView problem (From: Ryan Bates <email@hidden>)
 >Re: Easy TableView problem (From: "Barrett M. Conrad" <email@hidden>)

  • Prev by Date: Re: Easy TableView problem
  • Next by Date: Re: how to create status bar?
  • Previous by thread: Re: Easy TableView problem
  • Next by thread: Re: Easy TableView problem
  • Index(es):
    • Date
    • Thread