【问题标题】:Why does my app crash when I add an insert row to my table view?当我向表格视图添加插入行时,为什么我的应用程序会崩溃?
【发布时间】:2011-03-01 12:28:31
【问题描述】:

当用户按下编辑时,我正在尝试将带有插入控件(绿色加号)的行添加到我的表格视图中。到目前为止,我已经显示了插入行,但是如果用户在处于编辑模式时尝试滚动表格视图,应用程序将崩溃并出现以下错误:

* 由于未捕获的异常“NSRangeException”而终止应用程序,原因:“* -[_PFArray objectAtIndex:]: index (9) beyond bounds (9)”

我知道以前有人问过similar question,但由于我是编程新手,我可能需要更多的帮助。该问题的答案建议确保 numberOfRowsInSection 正确更新。我认为我的是,但我显然在某个地方犯了错误。

这是我目前在我的表视图控制器中得到的,它是我的 UINavigation 控制器的根视图控制器。目前它只是一个虚拟表 - 除了编辑按钮之外没有其他任何东西。

#import "RootViewController.h"
#import "AppDelegate_iPhone.h"
#import "Trip.h"

@implementation RootViewController
@synthesize trips = _trips;
@synthesize context = _context;


- (id)init
{
    self = [super init] ;
    if (self)
    {
         automaticEditControlsDidShow = NO;
    }
    return self ;
}


- (void)viewDidLoad {
    [super viewDidLoad];

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:[NSEntityDescription entityForName:@"Trip" inManagedObjectContext:_context]];   
    NSError *error;
    self.trips = [_context executeFetchRequest:fetchRequest error:&error];
    self.title = @"Trips";
    [fetchRequest release];

    // Display an Edit button for this view controller.
    self.navigationItem.rightBarButtonItem = self.editButtonItem;   
}


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    int rows = [_trips count];
    if (tableView.editing) rows++;
    return rows;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    Trip *info = [_trips objectAtIndex:indexPath.row];
    if (tableView.editing)
    {
        if (indexPath.row == 0)
            cell.textLabel.text = @"Add New Trip";
        if (indexPath.row == !0)
            cell.textLabel.text = info.tripName;
    }
    else
    {
        cell.textLabel.text = info.tripName;
    }
    return cell;    
}


- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
    int row = indexPath.row;

    if (self.editing && row == 0) {
        if (automaticEditControlsDidShow)
            return UITableViewCellEditingStyleInsert;
        return UITableViewCellEditingStyleDelete;
    }
    return UITableViewCellEditingStyleDelete;
}


- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    automaticEditControlsDidShow = NO;
    [super setEditing:editing animated:animated];

    NSArray *addRow = [NSArray arrayWithObjects:[NSIndexPath indexPathForRow:0 inSection:0],nil];
    [self.tableView beginUpdates];
    if (editing) {
        automaticEditControlsDidShow = YES;
        [self.tableView insertRowsAtIndexPaths:addRow withRowAnimation:UITableViewRowAnimationLeft];
    } else {
        [self.tableView deleteRowsAtIndexPaths:addRow withRowAnimation:UITableViewRowAnimationLeft];
    }
    [self.tableView endUpdates];
}


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

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
}

- (void)dealloc {
    [_trips release];
    [_context release];
    [super dealloc];
}


@end

谢谢!

【问题讨论】:

  • 我很好奇,== !0 语法是从哪里来的?这根本不是你想做的,但我想知道你为什么写那个......

标签: ios iphone uitableview cocoa-touch crash


【解决方案1】:

你的 tableView:cellForRowAtIndexPath: 方法的一部分是错误的

假设您的 tableview 处于编辑模式。 _trips 中有 10 个对象。

你告诉 tableview 数组中有 11 行:

if (tableView.editing) rows++;

tableview 将尝试在此处访问索引为 10 的元素:

Trip *info = [_trips objectAtIndex:indexPath.row];

但是你没有索引为 10 的元素。所以你会得到一个异常

您必须更改为您提供数组索引的逻辑。可能是这样的

if (tableView.editing) 
{   // tableview row count is _trips count + 1
    if (indexPath.row == 0)
        cell.textLabel.text = @"Add New Trip";
    if (indexPath.row != 0) {
        // realIndex = table view index - 1 
        Trip *info = [_trips objectAtIndex:indexPath.row - 1];
        cell.textLabel.text = info.tripName;
    }
}
else
{
    Trip *info = [_trips objectAtIndex:indexPath.row];
    cell.textLabel.text = info.tripName;
}

顺便说一句。 if (indexPath.row == !0) 做的事情与 if (indexPath.row != 0) 不同

【讨论】:

  • 谢谢!我一直在扯头发,但效果很好!当我们在这里时,您介意告诉我“==!0”和“!= 0”之间的区别吗?据我了解,一个表示“不等于 0”,另一个表示“等于除 0 以外的任何值”——两者之间是否经常存在有意义的差异?
  • @Ric x == !0 表示 x is equal to (not 0) 并且由于 not 0 表示 1 表达式 x == !0x == 1 相同。但是x != 0 表示x is (not equal) to 0,这对于所有非 0 都是正确的。
  • 谢谢 - 我想我明白了!我认为这只是一个 C 约定,将 (not 0) 视为与 (1) 相同。非常感谢您的帮助!
【解决方案2】:

这意味着您在数组中存储的行数是问题所在。请检查数组。崩溃是因为数组的元素总数超过了数组的限制

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-28
    • 2021-06-20
    • 2020-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多