Ios UITableView索引越界错误

Ios UITableView索引越界错误,ios,objective-c,Ios,Objective C,我在以下行遇到错误: cell1.textLabel.text = [settings objectAtIndex:indexPath.row]; 这是我收到的未捕获的初始错误: 这是我的密码: .h: @interface ViewController : UIViewController <UITableViewDataSource ,UITableViewDelegate>{ //Settings Table IBOutlet UITableView *se

我在以下行遇到错误:

cell1.textLabel.text = [settings objectAtIndex:indexPath.row];
这是我收到的未捕获的初始错误:

这是我的密码:

.h:

@interface ViewController : UIViewController <UITableViewDataSource ,UITableViewDelegate>{

    //Settings Table
    IBOutlet UITableView *settingTable;
    NSMutableArray *settings;
}

@property (nonatomic, retain) UITableView *settingTable;
@property (nonatomic, retain) NSMutableArray *settings;
@synthesize settingTable;
@synthesize settings;

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (!settings) {
        return 0;
    }

    if ([settings count] > 0){
        return [settings count];
    }
    else
        return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (settingTable) {

        NSLog(@"%@", settings);

        UITableViewCell *cell1 = [settingTable dequeueReusableCellWithIdentifier:@"MainCell1"];
        if (cell1 == nil) {
            cell1 = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MainCell1"];
        }

        cell1.textLabel.text = [settings objectAtIndex:indexPath.row];
        return cell1;
   }

// ...

- (void)viewDidLoad
{
    [super viewDidLoad];

    settingTable.delegate = self;
    settingTable.dataSource = self;

    //settings table
    settings = [[NSMutableArray alloc] initWithObjects:@"Downloads", @"Queue", @"FAQ", nil];
}

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


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

要清理代码,可以执行以下操作:

1.在cellForRowAtIndexPath方法中,使用

if([settings count]>0)
而不是

if(settingTable)
if(!settings){
    return 0;
}
if ([settings count] > 0){
    return [settings count];

}
else
    return 0;
2.在numberOfRowsInSection方法中,使用

if ([settings count] > 0){
    return [settings count];    
}
else
    return 0;
而不是

if(settingTable)
if(!settings){
    return 0;
}
if ([settings count] > 0){
    return [settings count];

}
else
    return 0;

代码中的上述更改将使代码工作正常。

要清除代码,可以执行以下操作:

1.在cellForRowAtIndexPath方法中,使用

if([settings count]>0)
而不是

if(settingTable)
if(!settings){
    return 0;
}
if ([settings count] > 0){
    return [settings count];

}
else
    return 0;
2.在numberOfRowsInSection方法中,使用

if ([settings count] > 0){
    return [settings count];    
}
else
    return 0;
而不是

if(settingTable)
if(!settings){
    return 0;
}
if ([settings count] > 0){
    return [settings count];

}
else
    return 0;

上述代码更改将使代码工作正常。

我将更改您的设置,使其初始化如下:

- (void)viewDidLoad
{
    [super viewDidLoad];
    settingTable.delegate = self;
    settingTable.dataSource = self;
}

- (NSMutableArray *)settings
{
    if (!_settings) settings = [[NSMutableArray alloc] initWithObjects:@"Downloads", @"Queue", @"FAQ", nil];
    return _settings;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return settings.count;
}

通过这种方式,您的设置对象始终处于初始化状态。

我将更改您的设置以进行如下初始化:

- (void)viewDidLoad
{
    [super viewDidLoad];
    settingTable.delegate = self;
    settingTable.dataSource = self;
}

- (NSMutableArray *)settings
{
    if (!_settings) settings = [[NSMutableArray alloc] initWithObjects:@"Downloads", @"Queue", @"FAQ", nil];
    return _settings;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return settings.count;
}

这样,您的设置对象总是被初始化。

问题在于您在UITableView中使用的是静态单元格。只需增加故事板中的行数。它是可以通过编程方式添加到表视图的最大单元格数


抱歉,我没有看到您没有使用情节提要。但是我的答案对于那些使用它的人来说是正确的。

问题是,您在UITableView中使用的是静态单元格。只需增加故事板中的行数。它是可以通过编程方式添加到表视图的最大单元格数


抱歉,我没有看到您没有使用情节提要。但是我的答案对那些使用它的人来说是正确的。

只要把它改成:

cell1.textLabel.text = [settings objectAtIndex:indexPath.row-1];

只需将行更改为:

cell1.textLabel.text = [settings objectAtIndex:indexPath.row-1];

如果您使用的是故事板和静态表,则可以使用以下两种方法之一:

1> 在返回行数的story boad中,单元格数应相同


2> 如果您想在故事板中保留一个单元格,则实现indentationLevelForRowAtIndexPath数据源方法。如果跟踪堆栈,则会发现需要实现的各种数据源方法,因为在动态原型表中,它会自行处理,但在静态中,我们需要实现数据源方法

如果您使用的是故事板和静态表,则两种方法之一可以工作:

1> 在返回行数的story boad中,单元格数应相同



2> 如果您想在故事板中保留一个单元格,则实现indentationLevelForRowAtIndexPath数据源方法。如果跟踪堆栈,则会发现需要实现的各种数据源方法,因为在动态原型表中,它会自行处理,但在静态表中,我们需要实现数据源方法

在崩溃之前,您是否可以编辑您的帖子并添加在其上使用NSLog时的“设置”外观?另外,如果您还没有这样做,我将设置一个异常断点,这将导致调试器在某些崩溃情况下稍早停止。请尝试先创建设置数组,然后为tableView设置委托和数据源属性,然后调用[tableView reloadData];我看不到您在哪里初始化
settingTable
tableView:cellforrowatinexpath:
的其余部分在哪里?你为什么还要检查
settingTable
是否为
nil
?你能在崩溃前编辑你的帖子并添加你在上面使用NSLog时的“设置”吗?另外,如果您还没有这样做,我将设置一个异常断点,这将导致调试器在某些崩溃情况下稍早停止。请尝试先创建设置数组,然后为tableView设置委托和数据源属性,然后调用[tableView reloadData];我看不到您在哪里初始化
settingTable
tableView:cellforrowatinexpath:
的其余部分在哪里?你为什么还要检查
settingTable
是否为
nil
?这会导致索引路径
(0,0)
崩溃。这会导致索引路径
(0,0)
崩溃。这并不能解释为什么
indexPath.row==3
会导致崩溃。上面发布的代码不会是3。由于设置对象是可变的,您是否在任何位置添加/删除项目?在slog中,它显示数组中的所有项目,但在打开TableView时仍会崩溃如果您在numberOfRowsInSection方法中设置断点/log on settings.count,则计数是否实际为3?另外,表视图的数据源是否连接到其他视图控制器?我可以看到数据源和委托如何指向两个不同的控制器可能会导致此问题。这并不能解释为什么
indepath.row==3
会导致崩溃。上面发布的代码不会是3。由于设置对象是可变的,您是否在任何位置添加/删除项目?在slog中,它显示数组中的所有项目,但在打开TableView时仍会崩溃如果您在numberOfRowsInSection方法中设置断点/log on settings.count,则计数是否实际为3?另外,表视图的数据源是否连接到其他视图控制器?我可以看出,让数据源和委托指向两个不同的控制器可能会导致这个问题。这并不能解决这个问题。为什么
indexPath.row==3
?@BrianNickel如果设置数组有3个元素,numberOfRowsInSection返回3(数组中的元素数,而不是数组的最高索引)。那么当调用indexPath.row时,它将是3,indexPath.row从0开始,结束于2。所以不会有错误。对,但问题是关于这个错误:
”-[\uu NSArrayM objectAtIndex::]:索引3超出界限[0..2]”
。这并不能解决问题。为什么
indexPath.row==3
?@BrianNickel如果设置数组有3个元素,numberOfRowsInSection返回3(数组中的元素数量,而不是数组的最高索引)。那么