You tested your app on the Simulator and everything is fine. You’ve install it on the iPhone, and when you reach a certain TableViewController your app crashes with the following message:

[UIAnimator removeAnimationsForTarget:].

How would you approach this issue?

Using common sense, try to set a breakpoint in each function from your TableViewController, then step through them to see in/after which function does the crash happens. In my case, the responsible code was found in the method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

It entered this function, once for each cell, but it crashed after exiting. As a new iOS developer, I was trying to set a couple of different UITableViewCell in one TableViewController. Here is a sample of the code I was using in the first version:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	// Setting a generic cell
	static NSString *CellIdentifier = @"Cell";
	UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

	if (cell == nil) {
		cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]
				autorelease];
	}

	// ... Other code

	// Replace generic cell with custom cell
	if(objectType == CMMUItemViewSectionSummary){
		NSArray *topLevelObjects = [[NSBundle mainBundle]
			loadNibNamed:@"SummaryCell"
			owner:nil
			options:nil];

		for(id currentObject in topLevelObjects){
			if([currentObject isKindOfClass:[SummaryCell class]]){
				cell = (SummaryCell *) currentObject;
				break;
			}
		}

		cell.summaryData = summaryData;
	} else if(objectType == CMMUItemViewSectionStatuses){
		NSArray *topLevelObjects = [[NSBundle mainBundle]
									loadNibNamed:@"ItemStatusCell"
									owner:nil
									options:nil];

		for(id currentObject in topLevelObjects){
			if([currentObject isKindOfClass:[ItemStatusCell class]]){
				cell = (ItemStatusCell *) currentObject;
				break;
			}
		}

		cell.statusesData = statusesData;
	} else {
		cell.textLabel.text = someDefaultData;
	}

	// Return the cell
	return cell;
}

As you can see in the above code, after I was getting a generic cell, I would try to replace it with a custom cell. I guess that somewhere after

tableView:cellForRowAtIndexPath:

some other piece of code was trying to cleanup the unused cells. Figuring this, it was pretty easy to get it fixed. Using the same sample code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
	NSString *CellIdentifier = @"Cell"; //Generic identifier
	UITableViewCell *cell;
	// Other code ...

	CellIdentifier = [NSString stringWithFormat:@"Cell%d", objectType]; //cell of my object type
	cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
	if(objectType == CMMUItemViewSectionSummary){
		if (cell == nil) {
			NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"SummaryCell"
				owner:nil
				options:nil];

			for(id currentObject in topLevelObjects){
				if([currentObject isKindOfClass:[SummaryCell class]]){
					cell = (SummaryCell *) currentObject;
					break;
				}
			}
		}

		cell.summaryData = summaryData;
	} else if(objectType == CMMUItemViewSectionStatuses){
		if (cell == nil) {
			NSArray *topLevelObjects = [[NSBundle mainBundle]
				loadNibNamed:@"ItemStatusCell"
				owner:nil
				options:nil];

			for(id currentObject in topLevelObjects){
				if([currentObject isKindOfClass:[ItemStatusCell class]]){
					cell = (ItemStatusCell *) currentObject;
					break;
				}
			}
		}

		cell.statusesData = statusesData;
	}

	if(cell == nil){
		cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
										   reuseIdentifier:CellIdentifier]
					autorelease];
	}

	return cell;
}

Even if is not the optimal way to use custom TableViewCells, it solves the crash problem.

Improvements and suggestions are welcomed.