在cellForRowAtIndexPath中使用索引的频繁outofbound - Obj C.

时间:2015-01-16 00:25:38

标签: 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
    }
}

我还在为2添加NSDictionary个额外广告位,因为广告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
}

回到i前两次调用cellForRowAtIndexPath我使用if statements为前两个单元格分配收集的数据。当我使用数据i

填充其他单元格时,我增加(if any)

以下是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"];

有关out of bounds崩溃原因的建议?

1 个答案:

答案 0 :(得分:1)

最可能的问题是您获取单元格数据的方式。您正在使用以下行中的实例变量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

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