ios - cellForRowAtIndexPath 中的索引频繁出界 - Obj C

标签 ios objective-c uitableview

经常当我拉起 UITableView 来刷新从服务器提取的内容时,它会崩溃并显示以下消息:

Terminating app due to uncaught exception 'NSRangeException', reason: 
'-[__NSCFArray objectAtIndex:]: index (4) beyond bounds (4)'

现在的问题是,我这边的数据每次都被设置到 NSDictionary 中,并且每次都有相同的数据,所以我知道我的服务器不会返回任何不合适的内容。

这里一切都是如何工作的,我有一个名为 i 的整数。 i 在细胞重新填充时将始终 = 0,基于:

-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if([indexPath row] == ((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row){
        //end of loading
        //for example [activityIndicator stopAnimating];
        i = 0;//<!-- reset the i so that when page reloads cells it does not fail
    }
}

我还为我的 NSDictionary 添加了 2 个额外插槽,因为插槽 01 是至关重要的部分。与填充前 2 个单元格的用户信息相关联:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [[self.dataGrabed_dictionary objectForKey:@"scheduled_times"] count] + 2;//<!-- by default we want to make sure 2 is being added no matter what. 1 = clients address and name, 2 = upcoming lawn care
}

所以回到icellForRowAtIndexPath的前2次调用,我使用if语句为前2个单元格分配收集的数据。当我用数据填充其他单元格(如果有)

时,我会增加i

这正是 cellForRowAtIndexPath 中发生的情况:

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

    NSLog(@"%d",i);
    self.tableView.separatorColor = [UIColor clearColor];// Get rid of speration border color

    static NSString *CellIdentifier = @"homecell";

    HomePageTimelineCell *cell = (HomePageTimelineCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    cell = [[HomePageTimelineCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
    [cell initTimelineCell];

    cell.backgroundColor = [UIColor clearColor];// Set the background color to the cell

    // lets check if there is any data
    if([self.dataGrabed_dictionary objectForKey:@"scheduled_times"] == nil && [self.dataGrabed_dictionary objectForKey:@"upcoming"] == nil)
    {
        //<!-- if the indexRow row = 0, this is the clients username and address
        if(indexPath.row == 0)
        {
            NSArray *get = [[SSKeychain allAccounts] init];
            NSString *username = [get[0] objectForKey:@"acct"];
            //<!-- Get keyname of the address and than point to that keyname and get data
            //NSString *KeyName = [[self.dataGrabed_dictionary allKeys] objectAtIndex: indexPath.row];
            //<!-- create uppercase strings
            NSString *upperCaseAddress = [[self.dataGrabed_dictionary objectForKey:@"client_address"] uppercaseString];
            NSString *upperCaseUsername = [username uppercaseString];
            //<!-- Set associated strings
            cell.addressLabel.text = upperCaseAddress;
            cell.usernameLabel.text = upperCaseUsername;
        }
        else if(indexPath.row == 1)
        {
        cell.contentView.backgroundColor = [self colorWithHexString:@"666666"];
        cell.button.backgroundColor = [self colorWithHexString:@"7ddcb8"];
        cell.button.tag = indexPath.row;

        [cell.button setTitle:@"schedule" forState:UIControlStateNormal];
        [cell.button setTitleColor:[self colorWithHexString:@"666666"] forState:UIControlStateNormal];
        /* Setup button action */
        //[cell.button addTarget:self action:@selector(onCustomAccessoryTapped:) forControlEvents:UIControlEventTouchUpInside];
        cell.dateLabel.tag = indexPath.row + 100; //<!-- 100 = date
        cell.dateLabel.text = @"Nothing Scheduled";//<!-- Set the Date
        [cell.contentView addSubview:cell.button];
        [cell.contentView addSubview:cell.nextLabel];
        [cell.contentView addSubview:cell.dayLabel];
        [cell.contentView addSubview:cell.dateLabel];
        }
    }
    else
    {

    //<!-- Set background color
    if (indexPath.row % 2) {
        cell.contentView.backgroundColor = [self colorWithHexString:@"77d1af"];
        //<!-- Set background and text color for even cells
        [cell.button setTitleColor:[self colorWithHexString:@"7ddcb8"] forState:UIControlStateNormal];
        cell.button.backgroundColor = [self colorWithHexString:@"666666"];
    } else {
        cell.contentView.backgroundColor = [self colorWithHexString:@"7ddcb8"];
        //<!-- Set background and text color for even cells
        [cell.button setTitleColor:[self colorWithHexString:@"7ddcb8"] forState:UIControlStateNormal];
        cell.button.backgroundColor = [self colorWithHexString:@"ffffff"];
    }
    //<!-- if the indexRow row = 0, this is the clients username and address
    if(indexPath.row == 0)
    {
        NSArray *get = [[SSKeychain allAccounts] init];
        NSString *username = [get[0] objectForKey:@"acct"];
        //<!-- Get keyname of the address and than point to that keyname and get data
        //NSString *KeyName = [[self.dataGrabed_dictionary allKeys] objectAtIndex: indexPath.row + 4];
        //<!-- create uppercase strings
        NSString *upperCaseAddress = [[self.dataGrabed_dictionary objectForKey:@"client_address"] uppercaseString];
        NSString *upperCaseUsername = [username uppercaseString];
        //<!-- Set associated strings
        cell.addressLabel.text = upperCaseAddress;
        cell.usernameLabel.text = upperCaseUsername;
    }
    //<!-- if the indexRow row = 1, this is the 2 cell and will show the most upcoming lawn schedule
    else if(indexPath.row == 1)
    {
        //<!-- Lets check if user even has an upcoming mowing date -->
        if([self.dataGrabed_dictionary objectForKey:@"upcoming"] == nil)
        {
            cell.contentView.backgroundColor = [self colorWithHexString:@"666666"];
            cell.button.backgroundColor = [self colorWithHexString:@"7ddcb8"];
            cell.button.tag = indexPath.row;

            [cell.button setTitle:@"schedule" forState:UIControlStateNormal];
            [cell.button setTitleColor:[self colorWithHexString:@"666666"] forState:UIControlStateNormal];
            /* Setup button action */
            //[cell.button addTarget:self action:@selector(onCustomAccessoryTapped:) forControlEvents:UIControlEventTouchUpInside];
            cell.dateLabel.tag = indexPath.row + 100; //<!-- 100 = date
            cell.dateLabel.text = @"Nothing Scheduled";//<!-- Set the Date
            [cell.contentView addSubview:cell.button];
            [cell.contentView addSubview:cell.nextLabel];
            [cell.contentView addSubview:cell.dayLabel];
            [cell.contentView addSubview:cell.dateLabel];
        }
        else
        {
            //<!-- create uppercase strings
            NSString *upperCaseDay = [[self.dataGrabed_dictionary objectForKey:@"upcoming_day"] uppercaseString];
            //<!-- create uppercase strings
            NSString *upperCaseDate = [[self.dataGrabed_dictionary objectForKey:@"upcoming_date"] uppercaseString];

            cell.contentView.backgroundColor = [self colorWithHexString:@"666666"];
            cell.button.backgroundColor = [self colorWithHexString:@"7ddcb8"];
            cell.button.tag = indexPath.row;

            [cell.button setTitle:@"change" forState:UIControlStateNormal];
            [cell.button setTitleColor:[self colorWithHexString:@"666666"] forState:UIControlStateNormal];
            /* Setup button action */
            //[cell.button addTarget:self action:@selector(onCustomAccessoryTapped:) forControlEvents:UIControlEventTouchUpInside];

            cell.dayLabel.text = upperCaseDay;//<!-- Set the day
            cell.dateLabel.tag = indexPath.row + 100; //<!-- 100 = date
            cell.dateLabel.text = upperCaseDate;//<!-- Set the Date
            [cell.contentView addSubview:cell.button];
            [cell.contentView addSubview:cell.nextLabel];
            [cell.contentView addSubview:cell.dayLabel];
            [cell.contentView addSubview:cell.dateLabel];
        }
    }
    else //<!-- Normal cell population
    {
        //<!-- Re edit labels positioning
        cell.dayLabel.frame = CGRectMake(9, 10, 200, 45);
        cell.dateLabel.frame = CGRectMake(9, 35, 300, 45);
        //<!-- Setup data called from server
        NSDictionary *innerClientData =[self.dataGrabed_dictionary objectForKey:@"scheduled_times"][i];
        NSString *innerClientDay =[self.dataGrabed_dictionary objectForKey:@"scheduled_times_day"][i];
        NSString *innerClientDate =[self.dataGrabed_dictionary objectForKey:@"scheduled_times_date"][i];
        //<!-- create uppercase strings
        NSString *upperCaseDay = [innerClientDay uppercaseString];
        //<!-- create uppercase strings
        NSString *upperCaseDate = [ innerClientDate uppercaseString];

        //<!-- Check to see if client paid
        if([[innerClientData objectForKey:@"client_paid"]  isEqual: @"0"])
        {
            NSString *amount = [innerClientData objectForKey:@"client_price"];
            NSString *pay = @"pay $";
            NSString * combined = [pay stringByAppendingString:amount];

            [cell.button setTitle:combined forState:UIControlStateNormal];
        }
        else if([[innerClientData objectForKey:@"client_paid"] isEqual: @"1"])
        {
            [cell.button setTitle:@"PAID" forState:UIControlStateNormal];
        }
        //[cell.button setTitleColor:[self colorWithHexString:@"666666"] forState:UIControlStateNormal];
        cell.button.tag = indexPath.row;
        /* Setup button action */
        //[cell.button addTarget:self action:@selector(onCustomAccessoryTapped:) forControlEvents:UIControlEventTouchUpInside];
        cell.dayLabel.text = upperCaseDay;//<!-- Set the day
        cell.dateLabel.tag = indexPath.row + 100; //<!-- 100 = date
        cell.dateLabel.text = upperCaseDate;//<!-- Set the Date
        [cell.contentView addSubview:cell.button];
        [cell.contentView addSubview:cell.dayLabel];
        [cell.contentView addSubview:cell.dateLabel];

        i++;

    }
    }
    return cell;
}

我对 NSDictionary 的分配如下所示:

NSString *responseString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSLog(@"responseString: %@",responseString);
            // GRAB STATUS OBJECT
NSDictionary* json = [NSJSONSerialization
                          JSONObjectWithData:returnData //1

                          options:kNilOptions
                          error:&error];
self.dataGrabed_dictionary = [json objectForKey:@"retrieved_data"];

关于为什么它会因越界而崩溃的建议?

最佳答案

最有可能的问题是您获取单元格数据的方式。您在以下行中使用了实例变量 i:

    NSDictionary *innerClientData =[self.dataGrabed_dictionary objectForKey:@"scheduled_times"][i];
    NSString *innerClientDay =[self.dataGrabed_dictionary objectForKey:@"scheduled_times_day"][i];
    NSString *innerClientDate =[self.dataGrabed_dictionary objectForKey:@"scheduled_times_date"][i];

那永远行不通。将 i 替换为 indexPath.row - 2

单元格可以按不同的顺序多次访问。

关于ios - cellForRowAtIndexPath 中的索引频繁出界 - Obj C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27975447/

相关文章:

ios - 如何动态更改 UITableView 中单元格的高度?

ios - 在 iOS 中检索所有联系人的电话号码

ios - Google 云计算在后台使用 Swift 推送通知

objective-c - 缺少依赖目标 "<PBXTargetDependency:0x201d16ca0:<no cached name>>"

objective-c - 是否可以与 iWork 进行一些互操作?

ios - 如何向 uiTableView Controller 添加滑动和标题 View 。?

ios - 你如何制作一个圆顶角和方形底角的 UIView

Objective-C:支持 ARC 的 iOS 照片查看器?

iphone - 我必须延长哪一个类?

swift - 在 Swift 的 UITableView 中添加、列出和删除项目