views:

901

answers:

2

I have this large table which works without errors, even if seems to me too slow compared to more complex cells i've opened from downloaded examples. The problem comes when i click a cell, then came back, in few seconds of scrolling fast the app is crashing at the line: charImage.image = [self imageForIndex:ch.charId];

If i delete it is crashing at the next line: titleLabel.text = ch.title;

Is anybody familiar with this? Thanks.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//NSLog(@"add a new cell at index path %@", indexPath);
// Each subview in the cell will be identified by a unique tag.
static NSUInteger const kTitleLabelTag = 2;
static NSUInteger const kCharImageTag = 3;
static NSString *kCellID = @"CellID";

// Configure the cell


// Declare references to the subviews which will display the char data.
UILabel *titleLabel = nil;
UIImageView *charImage = nil;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];

if (cell == nil) {
    // No reusable cell was available, so we create a new cell and configure its subviews.
 cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID] autorelease];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
 [cell setBackgroundColor:[UIColor clearColor]];
 //
    charImage = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"glyphs/a/1.png"]] autorelease];
    charImage.tag = kCharImageTag;
    charImage.autoresizingMask = UIViewAutoresizingNone;
    [cell.contentView addSubview:charImage];

    titleLabel = [[[UILabel alloc] initWithFrame:CGRectMake(60, 10, 215, 20)] autorelease];
    titleLabel.tag = kTitleLabelTag;
    titleLabel.font = [UIFont systemFontOfSize:16];
 titleLabel.textColor = [UIColor whiteColor];
 titleLabel.backgroundColor = [UIColor clearColor];
 titleLabel.adjustsFontSizeToFitWidth = YES;
    [cell.contentView addSubview:titleLabel];

} else {
    // A reusable cell was available, so we just need to get a reference to the subviews using their tags.
    charImage = (UIImageView *)[cell.contentView viewWithTag:kCharImageTag];
    titleLabel = (UILabel *)[cell.contentView viewWithTag:kTitleLabelTag];
}


// Get the specific info for this row.
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
Char *ch = (Char *)[charsList objectAtIndex:row+section*26];

// Set the relevant data for each subview in the cell.
// Set the image in the cell
charImage.image = [self imageForIndex:ch.charId];
[charImage sizeToFit];

int centerX = 30;
int centerY = 23;
CGSize size = charImage.frame.size;
charImage.frame = CGRectMake((int)(centerX - size.width / 2),
        (int)(centerY - size.height / 2),
        size.width, size.height);

titleLabel.text = ch.title;

return cell;

}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

InstantInsightAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
Char *ch = (Char *)[charsList objectAtIndex:row+26*section];

SqlQueries *db = [SqlQueries alloc];
NSArray *glyphsList = [db readGlyphsFromDatabaseAtId: ch.charId];
NSArray *charDescription = [db readMoreInfoFromDatabaseAtId: ch.charId];
Char *charDetails = [db readInstructionsAndQuotesFromDatabaseAtId: ch.charId];
[db release];
[ch release];

// Navigation logic -- create and push a new view controller
self.glyphsView = [[GlyphsViewController alloc] initWithStyle:UITableViewStyleGrouped];

self.glyphsView.glyphsList = glyphsList;
self.glyphsView.charDetails = charDetails;
self.glyphsView.charDescription = charDescription;
[delegate.navController pushViewController:self.glyphsView animated:YES];
[self.glyphsView release];
self.glyphsView = nil;

}

+1  A: 

What kind of "crashing"? An EXC_BAD_ACCESS (dereferencing a pointer that doesn't point to a valid location)? Or an objc_exception_throw of some kind?

Assuming you mean an EXC_BAD_ACCESS...

This would be because the "ch" value returned from [charsList objectAtIndex:row+section*26] is not a valid object.

The exact reason for this you'll need to discover yourself but the most likely cause is that you've released the object one too many times. There is also the possibility that the object was not a valid Objective-C object when it was inserted into the NSArray.

Sometimes it helps to set NSZombieEnabled (command-option-x, go to the Arguments tab and add name=NSZombieEnabled and value=1 to the environment variables) since this will throw an exception immediately if you try to use a deallocated object.

--

Unrelated stylistic point: you're allocating SqlQueries but not initializing it. If you alloc, always, always init. i.e. [[SqlQueries alloc] init]. If you don't care about init because you don't have any instance variables, then you shouldn't have an alloc anyway, your methods should be class methods instead.

Matt Gallagher
Thank you for the detailed explanations. I think i can put something into the init of the SqlQueries.Now, i'm sure that my error is that one with the exception, because there's where i get the idea of putting a try catch, and sadly is still crashing, the nslog from the catch is not called.I'm not sure what else to tell about my code.
Cristi Băluță
You can't catch an EXC_BAD_ACCESS. You need to work out why your objects in the charList are invalid. Use breakpoints in the debugger or NSLog the whole charList on a regular basis to see when it is going wrong (NSLog will crash the program once a charList object becomes invalid).Chances are that you have code somewhere that is releasing (or autoreleasing) one of the Char objects when it never alloc'd or retained it -- this is causing the Char object to be invalidated even though it is still needed by the charList array.
Matt Gallagher
So yes, i looked more carefully to see if i'm deallocing the Char object from the array as you said, and i was doing it. The answer is to delete this line: [ch release];Thanks again.
Cristi Băluță
A: 

Here is a detailed error: it doesn't say anything but i'm sure i've saw something with an exception

[Session started at 2009-10-05 07:41:25 +0300.] GNU gdb 6.3.50-20050815 (Apple version gdb-967) (Tue Jul 14 02:11:58 UTC 2009) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-apple-darwin".sharedlibrary apply-load-rules all Attaching to process 96464. (gdb) ^C where

#0  0x95fd5688 in objc_msgSend ()
#1  0x00002f60 in -[IndexViewController tableView:cellForRowAtIndexPath:] (self=0xd19610, _cmd=0x319a6b9c, tableView=0x101be00, indexPath=0xd2e890) at /Users/Cristi/Documents/xcode - iPhone/Instant Insight/InstantInsight/Classes/IndexViewController.m:115
#2  0x30944bd0 in -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] ()
#3  0x3093e1fc in -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] ()
#4  0x309501f1 in -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow] ()
#5  0x30947715 in -[UITableView layoutSubviews] ()
#6  0x00b3dd94 in -[CALayer layoutSublayers] ()
#7  0x00b3db55 in CALayerLayoutIfNeeded ()
#8  0x00b3d3ae in CA::Context::commit_transaction ()
#9  0x00b3d022 in CA::Transaction::commit ()
#10 0x00b452e0 in CA::Transaction::observer_callback ()
#11 0x30245c32 in __CFRunLoopDoObservers ()
#12 0x3024503f in CFRunLoopRunSpecific ()
#13 0x30244628 in CFRunLoopRunInMode ()
#14 0x32044c31 in GSEventRunModal ()
#15 0x32044cf6 in GSEventRun ()
#16 0x309021ee in UIApplicationMain ()
#17 0x00002718 in main (argc=1, argv=0xbfffee50) at /Users/Cristi/Documents/xcode - iPhone/Instant Insight/InstantInsight/main.m:14
Cristi Băluță