Reputation: 1663
In my program I'm creating a couple of custom UIViewCells loaded from a nib file:
[[NSBundle mainBundle] loadNibNamed:@"CustomCells" owner:self options:nil];
Once they're loaded i set them up and return from the function:
if (indexpath.row == 1) {
[nibTextInputer setupWithName:@"notes" ...];
return nibTextInputer;
} else {
[nibSelectInputer setupWithName:@"your_choice" ...];
return nibSelectInputer;
};
Where nibTextInputer is of my class (AFTextInputer) and nibSelectInputer is of my other class (AFTextInputer). Both classes subclass from UITableViewCell.
It all works fine, BUT breaks when I add caching to that:
Boolean inCache = false;
if (indexPath.row == 1) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"nibTextInputer"];
if (cell != nil) {
NSLog(@"%@", [cell description]); // prints out ok, correct type.
nibTextInputer = (AFTextInputer*) cell;
inCache = true;
};
};
if (!inCache) {
[[NSBundle mainBundle] loadNibNamed:@"CustomCells" owner:self options:nil];
}
Once I add the above EXC_BAD_ACCESS starts appearing in random places, usually with no additional information and sometimes with this error:
-[CALayer prepareForReuse]: unrecognized selector sent to instance
or even
-[UIImage prepareForReuse]: unrecognized selector sent to instance
The location of EXC_BAD_ACCESS is seemingly random. Sometimes it's right after "dequeue", sometimes outside of the function..
I guess the problem lies within my implementation of custom UIViewCells, but I have no idea where to start looking..
Ideas?
Upvotes: 0
Views: 1609
Reputation: 13044
You have an over-release occurring on your UITableViewCell
. -[UITableViewCell prepareForReuse]
is called just before returning from -[UITableView dequeueReusableCellWithIdentifier:]
, but when it is being called the cell is no longer there but instead a CALayer, UIImage or something that you don't have access to.
The problem is likely in the way you are loading the custom cell. For what it's worth, this is how I typically do it:
static NSString *CellIdentifier = @"CustomCell"; // This string should also be set in IB
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
cell = nibCell; // nibCell is a retained IBOutlet which is wired to the cell in IB
}
// Set up the cell...
Upvotes: 2
Reputation: 27601
This is probably where you're going to run into problems:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"nibTextInputer"];
The UITableView class lumps all of your cells into the same pool for reuse; it doesn't know that some cells are one kind of subclass (i.e. AFTextInputer) and some cells are another kind of subclass (i.e. AFTextInputer). So when you dequeue a cell in the if (indexPath.row == 1)
block, you might be getting the wrong kind of subclassed cell back. The "identifier" is just a string that indicates to the built-in cache which table's cells you're referencing; it doesn't actually use that string to dig into the cache to find an object with a matching subclass name.
P.S. Why are you using a type called Boolean
instead of the "built-in" BOOL
?
Upvotes: 0