iOS NSArray objectAtIndex超出界限

时间:2013-04-26 19:54:08

标签: ios objective-c indexing nsarray

我有一个UITableView,它是从一个从XML Feed解析的数据数组中填充的。我努力找到这个错误的原因,并想知道是否有人可以帮助我。错误不会经常发生。它仅在数组计数很大时发生,例如10-15个对象,然后刷新一次后,它们的数组就是一个较小的数字,如3-4个对象。通常在这一行上抛出错误:FCCall * currentCall = [[dataController callsArray] objectAtIndex:((indexPath.row - 1)/ 2)];我添加了一个异常断点来打破On Throw for All Exception,下面是它返回的内容。我理解错误说的是什么,但找不到原点,很难重新制作。

CoreFoundation`-[__NSArrayM objectAtIndex:]:
0x329cce54:  push   {r4, r5, r7, lr}
0x329cce56:  add    r7, sp, #8
0x329cce58:  sub    sp, #8
0x329cce5a:  movw   r1, #62216
0x329cce5e:  mov    r4, r2
0x329cce60:  movt   r1, #2113
0x329cce64:  add    r1, pc
0x329cce66:  ldr    r1, [r1]
0x329cce68:  ldr    r1, [r0, r1]
0x329cce6a:  cmp    r1, r4
0x329cce6c:  bhi    0x329ccef8                ; -[__NSArrayM objectAtIndex:] + 164
0x329cce6e:  movw   r0, #49640
0x329cce72:  cmp    r1, #0
0x329cce74:  movt   r0, #2111
0x329cce78:  add    r0, pc
0x329cce7a:  ldr    r0, [r0]
0x329cce7c:  ldr    r0, [r0]
0x329cce7e:  beq    0x329cce9c                ; -[__NSArrayM objectAtIndex:] + 72
0x329cce80:  movw   r2, #17054
0x329cce84:  subs   r5, r1, #1
0x329cce86:  movt   r2, #2113
0x329cce8a:  movw   r3, #61062
0x329cce8e:  movt   r3, #16
0x329cce92:  add    r2, pc
0x329cce94:  add    r3, pc
0x329cce96:  strd   r4, r5, [sp]
0x329cce9a:  b      0x329cceb2                ; -[__NSArrayM objectAtIndex:] + 94
0x329cce9c:  movw   r2, #17044
0x329ccea0:  movt   r2, #2113
0x329ccea4:  movw   r3, #61034
0x329ccea8:  movt   r3, #16
0x329cceac:  add    r2, pc
0x329cceae:  str    r4, [sp]
0x329cceb0:  add    r3, pc
0x329cceb2:  movs   r1, #0
0x329cceb4:  bl     0x329dce60                ; CFStringCreateWithFormat
0x329cceb8:  bl     0x329c897c                ; CFMakeCollectable
0x329ccebc:  mov    r1, r0
0x329ccebe:  movs   r0, #0
0x329ccec0:  bl     0x329ffa8c                ; _CFAutoreleasePoolAddObject
0x329ccec4:  movw   r2, #50122
0x329ccec8:  mov    r3, r0
0x329cceca:  movt   r2, #2111
0x329ccece:  movw   r1, #25010
0x329cced2:  add    r2, pc
0x329cced4:  movt   r1, #2112
0x329cced8:  movw   r0, #26280
0x329ccedc:  ldr    r2, [r2]
0x329ccede:  add    r1, pc
0x329ccee0:  movt   r0, #2112
0x329ccee4:  ldr    r1, [r1]
0x329ccee6:  movs   r4, #0
0x329ccee8:  add    r0, pc
0x329cceea:  str    r4, [sp]
0x329cceec:  ldr    r0, [r0]
0x329cceee:  ldr    r2, [r2]
0x329ccef0:  blx    0x32abfeec                ; symbol stub for: -[NSMutableOrderedSet removeObjectsInRange:inOrderedSet:]
0x329ccef4:  blx    0x32abfe8c                ; symbol stub for: -[NSMutableOrderedSet removeObjectsAtIndexes:]
0x329ccef8:  movw   r1, #62064
0x329ccefc:  movt   r1, #2113
0x329ccf00:  movw   r3, #62048
0x329ccf04:  add    r1, pc
0x329ccf06:  movt   r3, #2113
0x329ccf0a:  movw   r2, #62048
0x329ccf0e:  ldr    r1, [r1]
0x329ccf10:  add    r3, pc
0x329ccf12:  movt   r2, #2113
0x329ccf16:  ldr    r3, [r3]
0x329ccf18:  add    r2, pc
0x329ccf1a:  ldr    r2, [r2]
0x329ccf1c:  ldr    r1, [r0, r1]
0x329ccf1e:  ldr    r3, [r0, r3]
0x329ccf20:  ldr    r0, [r0, r2]
0x329ccf22:  add.w  r2, r4, r1, lsr #2
0x329ccf26:  sub.w  r1, r2, r3, lsr #2
0x329ccf2a:  lsrs   r3, r3, #2
0x329ccf2c:  cmp    r3, r2
0x329ccf2e:  it     hi
0x329ccf30:  movhi  r1, r2
0x329ccf32:  ldr.w  r0, [r0, r1, lsl #2]
0x329ccf36:  add    sp, #8
0x329ccf38:  pop    {r4, r5, r7, pc}
0x329ccf3a:  nop    
0x329ccf3c:  nop    
0x329ccf3e:  nop 

代码:

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

    // Returns the cell for the given indexPath 
    static NSString *cellidentifier1 = @"cell1";
    static NSString *cellidentifier2 = @"cell2";

    self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"dark-background.jpg"]];
    self.tableView.separatorColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"dark-background.jpg"]];

    // Invisible Cell
    if (indexPath.row % 2 == 0) {

        UITableViewCell * cell2 = [theTableView dequeueReusableCellWithIdentifier:cellidentifier2];

        if (cell2 == nil) {

            cell2 = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellidentifier2];
            [cell2.contentView setAlpha:0];
            [cell2 setUserInteractionEnabled:NO];
            [cell2 setBackgroundColor:[UIColor clearColor]];
        }
        return cell2;
    }

    // Standard Cell    
    SideSwipeTableViewCell *cell = (SideSwipeTableViewCell *)[theTableView dequeueReusableCellWithIdentifier:cellidentifier1];

    if (cell == nil) {

        cell = [[SideSwipeTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellidentifier1];
    }

    if ([dataController numberOfCalls] >= 1) {

        FCCall *currentCall = [[dataController callsArray] objectAtIndex:((indexPath.row - 1 ) / 2)];

        cell.callLabel.text = currentCall.call;
        cell.locationLabel.text = currentCall.location;
        cell.wcccaNumberLabel.text = currentCall.wcccaNumber;
        cell.callNumberLabel.text = currentCall.callnumber;

        // Remove leading white space from units string
        NSString *units = [currentCall.units stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

        cell.unitsLabel.text = units;
        cell.stationLabel.text = currentCall.station;
    }
    return cell;
}

刷新数组的方法:

- (void)refreshData:(id)object success:(void (^)(NSURLRequest *request, NSURL *url, NSArray *calls))success failure:(void (^)(NSURLRequest *request, NSURL *url, NSError *error))failure
{
    NSLog(@"Refresh Started");

    // Start the network activity indicator
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

    // Check to make sure we can even make an HTTP request
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.wccca.com/PITS"]];
    AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        NSLog(@"Reachable");

        // Get the URL we are going to use to parse with
        [FCDataController parserURL:[NSURL URLWithString:@"http://www.wccca.com/PITS"] completion:^(NSURL *url) {

            NSURLRequest *parserRequest = [NSURLRequest requestWithURL:url];
            AFXMLRequestOperation *operation = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:parserRequest success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {

                // Remove all data from our previous calls aray
                [self performSelectorOnMainThread:@selector(removeCallsFromArray) withObject:nil waitUntilDone:YES];

                // Set the delegate for the XMLParser and start the parse operation
                XMLParser.delegate = self;
                BOOL successful = [XMLParser parse];

                // Determine if the parse operation was a success or not
                if (!successful) {

                    // Return the failure block because the parser failed
                    failure(request, url, [FCErrors parserError]);

                    // Stop the network activity indicator
                    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
                }
                else {

                    // Return the success block
                    success(request, url, calls);

                    // Stop the network activity indicator
                    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
                }

                NSLog(@"Refresh Finished");

            } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, NSXMLParser *XMLParser) {

                NSLog(@"AFXMLOperation Error: %@", error.localizedDescription);

                // Remove all data from our previous calls aray
                [self performSelectorOnMainThread:@selector(removeCallsFromArray) withObject:nil waitUntilDone:YES];

                failure(parserRequest, url, [FCErrors badURLError]);

                // Stop the network activity indicator
                [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

                NSLog(@"Refresh Finished");
            }];
            [operation start];
        }];

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        NSLog(@"Unreachable. AFHTTPRequestOperation Error: %@", error.localizedDescription);

        // Remove all data from our previous calls aray
        [self performSelectorOnMainThread:@selector(removeCallsFromArray) withObject:nil waitUntilDone:YES];

        failure(request, nil, [FCErrors networkError]);

        // Stop the network activity indicator
        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

        NSLog(@"Refresh Finished");
    }];
    [requestOperation start];
}

1 个答案:

答案 0 :(得分:1)

如果您的基础数据模型已更改(例如刷新表格需要显示的数据),则需要在reloadData上调用tableView,否则它可能会请求某行的数据不再存在。