本文介绍了UITableView 在 vi​​ewDidLoad 中间初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个正在初始化的 VC,其中有一个 View.在 View 中有一个 UITableViewUIButtonUIImage.

突然间,我正在搞乱按钮属性:

断言失败 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:]

经过进一步挖掘,是因为我的代码:

UINib *animCellNib = [UINib nibWithNibName:@"IoUISEAnimationDetailListingCell" bundle:nil];[animationDetailsTableView registerNib:animCellNib forCellReuseIdentifier:@"AnimationDetailListingCell"];

没有被执行.进一步挖掘在我的 viewDidLoad 方法的顶部,它跳转到初始化 tableView.因此,从我的方法名称跟踪中,您可以看到它以 numberOfSectionsInTableView 开头.虽然这只发生在我的 viewDidLoad

中的几行

2011-10-12 15:43:42.113 io[5052:11903] - initWithNibName:bundle:2011-10-12 15:43:42.116 io[5052:11903] <IoUISEAnimationDetailsViewController: 0x764c460>- viewDidLoad当前语言:自动;当前目标-c2011-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] *** 断言失败 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:],/SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:60722011-10-12 15:43:49.018 io[5052:11903] *** 由于未捕获的异常NSInternalInconsistencyException"而终止应用程序,原因:UITableView dataSource 必须从 tableView:cellForRowAtIndexPath 返回一个单元格:"

viewDidLoad 方法中,在我设置 saveButton.titleLabel.lineBreakMode 之后和 saveButton setBackgroundImage:newImage 之前,它会跳转到 >numberOfSectionsInTableView 方法.

由于我的 registerNib: forCellReuseIdentifier: 代码在按钮代码之后,单元格 nib 未注册,从而导致我的 dequeueReusableCellWithIdentifier 返回 nil 并崩溃.>

关于为什么会发生这种情况的任何提示?

这是viewDidLoad的代码:

- (void)viewDidLoad {if (IoUIDebug & IoUIDebugSelectorNames) {NSLog(@"%@ - %@", [自我描述], NSStringFromSelector(_cmd) );}[超级viewDidLoad];//创建一个空的 Tableview 并窃取它的背景.//设置我们的背景UITableView *tv = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStyleGrouped];UIView *backgroundView = tv.backgroundView;[self.view addSubview:backgroundView];[电视发布];//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.contentHorizo​​ntalAlignment = UIControlContentHorizo​​ntalAlignmentCenter;saveButton.titleLabel.textAlignment = UITextAlignmentCenter;saveButton.titleLabel.lineBreakMode = UILineBreakModeCharacterWrap;[saveButton setTitle:NSLocalizedStringFromTable(@"保存动画标签",@"ScreenEditor",@"保存动画标签") 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];//如果父视图使用自定义颜色或渐变绘制,请使用透明颜色saveButton.backgroundColor = [UIColor clearColor];if (UIAppDelegate.ioMainViewController.currentDeployment.readOnlyMode == NO) {//如果部署是可编辑的,则仅设置长按..InstructionLabel.text = NSLocalizedStringFromTable(@"动画详细说明", @"ScreenEditor", @"");} 别的 {InstructionLabel.text = NSLocalizedStringFromTable(@"Locked Message", @"Configuration",@"");}IoCDElementAnimation * currentAnimation = UIAppDelegate.ioMainViewController.currentElementAnimation;如果(当前动画){newAnimation = 当前动画;selectedSysCDAnimation = currentAnimation.sysAnimation;selectedIoCDTag = currentAnimation.tag;动画保存 = 是;} 别的 {selectedSysCDAnimation = nil;selectedIoCDTag = nil;动画保存=否;}UINIb *animCellNib = [UINib nibWithNibName:@"IoUISEAnimationDetailListingCell" bundle:nil];[animationDetailsTableView registerNib:animCellNib forCellReuseIdentifier:@"AnimationDetailListingCell"];//将我们的 TableView 背景设置为清除,以便我们可以看到我们的新背景[animationDetailsTableView setBackgroundView:nil];[animationDetailsTableView setBackgroundColor:[UIColor clearColor]];[self refreshContents:nil];[self setupOrientation:[[UIApplication sharedApplication] statusBarOrientation]];[self.view setNeedsLayout];}

在这个方法中,dequeueReusableCellWithIdentifier: 返回 nil.由于 viewDidLoad 中的 registerNib 代码尚未运行,因此无法找到 AnimationDetailListingCell 标识符.看起来所有 viewDidLoad 都应该在它开始初始化 tableview 之前运行,对吗?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {if (IoUIDebug & IoUIDebugSelectorNames) {NSLog(@"%@ - %@", [自我描述], NSStringFromSelector(_cmd) );}UITableViewCell *cell;cell = [animationDetailsTableView dequeueReusableCellWithIdentifier:@"AnimationDetailListingCell"];//此时单元格为零![self configureCell:cell atIndexPath:indexPath];返回单元格;}
解决方案

我遇到了同样的错误.我认为这是因为调整某些按钮属性意味着需要设置视图(显然是懒惰创建的),这意味着表需要准备就绪,而现在还没有,可能是因为它的数据源尚未连接或者其他的东西.尝试将您的按钮调整移到 viewDidLoad 方法中;这对我有用.

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;
}
解决方案

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.

这篇关于UITableView 在 vi​​ewDidLoad 中间初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 09:15