问题
I have a VC that I'm initializing, and in it is a View
. In the View
is a UITableView
, UIButton
, and UIImage
.
I was messing with button attributes when all of a sudden, wham:
Assertion failure in -[UITableView _createPreparedCellForGlobalRow:withIndexPath:]
After further digging, it was because my code:
UINib *animCellNib = [UINib nibWithNibName:@"IoUISEAnimationDetailListingCell" bundle:nil];
[animationDetailsTableView registerNib:animCellNib forCellReuseIdentifier:@"AnimationDetailListingCell"];
was not getting executed. Further digging revealed in the top of my viewDidLoad
method, it jumped into initializing the tableView
. So from my method name trace, you can see that it starts with the numberOfSectionsInTableView
. Though this only happens a few lines into my viewDidLoad
2011-10-12 15:43:42.113 io[5052:11903] <IoUISEAnimationDetailsViewController: 0x764c460> - initWithNibName:bundle:
2011-10-12 15:43:42.116 io[5052:11903] <IoUISEAnimationDetailsViewController: 0x764c460> - viewDidLoad
Current language: auto; currently objective-c
2011-10-12 15:43:49.017 io[5052:11903] <IoUISEAnimationDetailsViewController: 0x764c460> - numberOfSectionsInTableView:
2011-10-12 15:43:49.017 io[5052:11903] <IoUISEAnimationDetailsViewController: 0x764c460> - tableView:titleForHeaderInSection:
2011-10-12 15:43:49.017 io[5052:11903] <IoUISEAnimationDetailsViewController: 0x764c460> - tableView:titleForFooterInSection:
2011-10-12 15:43:49.017 io[5052:11903] <IoUISEAnimationDetailsViewController: 0x764c460> - tableView:numberOfRowsInSection:
2011-10-12 15:43:49.017 io[5052:11903] <IoUISEAnimationDetailsViewController: 0x764c460> - tableView:cellForRowAtIndexPath:
2011-10-12 15:43:49.017 io[5052:11903] *** Assertion failure in -[UITableView _createPreparedCellForGlobalRow:withIndexPath:], /SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:6072
2011-10-12 15:43:49.018 io[5052:11903] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:'
In the viewDidLoad
method, sometime after I set saveButton.titleLabel.lineBreakMode
and before saveButton setBackgroundImage:newImage
it jumps to the numberOfSectionsInTableView
method.
Since my code for registerNib: forCellReuseIdentifier:
is after the button code, the cell nib is not registered, thus causing my dequeueReusableCellWithIdentifier
to return nil and crash.
Any tips on why this is happening?
Here is the code for viewDidLoad
:
- (void)viewDidLoad {
if (IoUIDebug & IoUIDebugSelectorNames) {
NSLog(@"%@ - %@", [self description], NSStringFromSelector(_cmd) );
}
[super viewDidLoad];
// Create an Empty Tableview and steal its Background.
//set our background to it
UITableView *tv = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStyleGrouped];
UIView *backgroundView = tv.backgroundView;
[self.view addSubview:backgroundView];
[tv release];
// CGRect backgroundFrame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
//[backgroundView setFrame:backgroundFrame];
[self.view sendSubviewToBack:backgroundView];
saveButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
saveButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
saveButton.titleLabel.textAlignment = UITextAlignmentCenter;
saveButton.titleLabel.lineBreakMode = UILineBreakModeCharacterWrap;
[saveButton setTitle:NSLocalizedStringFromTable(@"Save Animation Label",@"ScreenEditor",@"Save Animation Label") forState:UIControlStateNormal];
[saveButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
saveButton.titleLabel.font = [UIFont boldSystemFontOfSize:17];
UIImage *newImage = [[UIImage imageNamed:@"BlueButtonSmall.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0];
[saveButton setBackgroundImage:newImage forState:UIControlStateNormal];
UIImage *newPressedImage = [[UIImage imageNamed:@"BlueButtonSmallPressed.png"] stretchableImageWithLeftCapWidth:12.0 topCapHeight:0.0];
[saveButton setBackgroundImage:newPressedImage forState:UIControlStateHighlighted];
// in case the parent view draws with a custom color or gradient, use a transparent color
saveButton.backgroundColor = [UIColor clearColor];
if (UIAppDelegate.ioMainViewController.currentDeployment.readOnlyMode == NO) { // Only setup for the long press if the deployment is editable..
instructionLabel.text = NSLocalizedStringFromTable(@"Animation Details Instructions", @"ScreenEditor", @"");
} else {
instructionLabel.text = NSLocalizedStringFromTable(@"Locked Message", @"Configuration",@"");
}
IoCDElementAnimation * currentAnimation = UIAppDelegate.ioMainViewController.currentElementAnimation;
if (currentAnimation) {
newAnimation = currentAnimation;
selectedSysCDAnimation = currentAnimation.sysAnimation;
selectedIoCDTag = currentAnimation.tag;
animationSaved = YES;
} else {
selectedSysCDAnimation = nil;
selectedIoCDTag = nil;
animationSaved = NO;
}
UINib *animCellNib = [UINib nibWithNibName:@"IoUISEAnimationDetailListingCell" bundle:nil];
[animationDetailsTableView registerNib:animCellNib forCellReuseIdentifier:@"AnimationDetailListingCell"];
// set our TableView Background to clear so we can see our new background
[animationDetailsTableView setBackgroundView:nil];
[animationDetailsTableView setBackgroundColor:[UIColor clearColor]];
[self refreshContents:nil];
[self setupOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
[self.view setNeedsLayout];
}
In this method, dequeueReusableCellWithIdentifier:
returns nil. The AnimationDetailListingCell identifier cannot be found as the registerNib
code in viewDidLoad
has not yet run. It would seem like all of viewDidLoad
should run before it breaks out to initialize the tableview, right?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (IoUIDebug & IoUIDebugSelectorNames) {
NSLog(@"%@ - %@", [self description], NSStringFromSelector(_cmd) );
}
UITableViewCell *cell;
cell = [animationDetailsTableView dequeueReusableCellWithIdentifier:@"AnimationDetailListingCell"];
// cell at this point in nil!
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
回答1:
I had the same error. I think it is because adjusting certain button properties means the view (apparently lazily created) needs to be set up, which means the table needs to be ready to go, and it isn't yet, perhaps because its datasource hasn't been connected or something. Try moving your button adjustment to later in the viewDidLoad method; that worked for me.
来源:https://stackoverflow.com/questions/7747679/uitableview-getting-initialized-in-the-middle-of-viewdidload