第二次运行代码时出现Xcode NSRangeException

时间:2013-05-23 14:42:14

标签: ios xcode arrays uitableview

现在我知道NSRangeException是什么。我没有得到的是为什么在第一次运行我的代码时它很好,但是当第二次失败时设置相同的代码(和变量)。即使单步执行代码,我也看不出它与第一次运行的不同之处。

整个代码从我的php api获取一组JSON值(基本上只是客户信息,预订的单位,日期等)。它过去只是在UITableView中显示它,我决定按日期对表格进行分组它被预订了(在我看来,Apple应该有一个更好的方法来做这个,也许扩展他们的UITableView?)

我的.h

    @interface LTBViewController : UIViewController {
IBOutlet UITableView *mainTableView;

NSArray *tickets;  //for storing our serialized JSON
NSMutableData *data; //for appending our JSON as we're getting it
NSString *token; //for security authentication with our custom API


NSMutableArray *days; //for storing any days with bookings retrieved from tickets
NSMutableDictionary *groupedTickets; //for storing tickets to correlate to days
NSArray *filteredArray; //for our finalized output
}
@end

我的大多数.m(重要部分)

- (void)viewDidAppear:(BOOL)animated
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://myurl.com/api/api.php?api=%@&function=%@", token, @"active"]];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [NSURLConnection connectionWithRequest:request delegate:self];



    //[[NSURLConnection alloc] initWithRequest:request delegate:self]; old way of doing it
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    //initialize from our settings file and make sure we're authenticated
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    token = [defaults objectForKey:@"api_token"];
    NSLog(@"%@",token);

    //initialize our sorting arrays
    days = [[NSMutableArray alloc] init];
    groupedTickets = [[NSMutableDictionary alloc] init];
    filteredArray = [[NSArray  alloc] init];
}


- (void)groupTable {


    NSUInteger count = 0;
    for (LTBViewController *ticket in tickets)
    {

        NSString *date = [[tickets objectAtIndex:count] objectForKey:@"dateIn"];
        if (![days containsObject:date])
        {
            [days addObject:date];
            [groupedTickets setObject:[NSMutableArray arrayWithObject:ticket] forKey:date];
        }
        else
        {
            [((NSMutableArray*)[groupedTickets objectForKey:date]) addObject:ticket];
        }
        count +=1;

    }
    count = 0;
    [mainTableView reloadData];
}


//for when we get a response
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    data = [[NSMutableData alloc] init];
}


//for getting data
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)thedata
{
    [data appendData:(thedata)];

}


//for when connection finished
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    tickets = [NSJSONSerialization JSONObjectWithData:data options:NO error:nil];

    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

    [self groupTable]; //starts our grouping methods
}


//for when connection fails
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Could not connect to server" delegate:nil cancelButtonTitle:@"dismiss" otherButtonTitles:nil, nil];
    [errorView show];
}

//overriding the "delete" text for our UITableView
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath {
    return @"Close Ticket";
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    NSString *date = [days objectAtIndex:section];
    return date;
}


- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [days count];
}


- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSString *date = [days objectAtIndex:section];
    NSLog(@"%@", date);
    return [[groupedTickets objectForKey:date] count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MainCell"];

    tableView.layer.cornerRadius = 5.0; //rounds our table corners

    if(cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:@"MainCell"];
    }

//I'm sure theres a better way to do this but it works for now

    NSString *date = [days objectAtIndex:[indexPath section]];

    NSPredicate *search = [NSPredicate predicateWithFormat:@"dateIn == %@", date];

    filteredArray = [tickets filteredArrayUsingPredicate:search];

//这就是第二次在索引1处失败的原因

cell.textLabel.text = [NSString stringWithFormat:@"%@",[[filteredArray objectAtIndex:[indexPath row]] objectForKey:@"ticketnumber"] ]; 

    cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", [[filteredArray objectAtIndex:[indexPath row]] objectForKey:@"customerName"]];

    return cell;
}

单击某个项目时,它会移动到另一个视图控制器(可以正常工作),但是当按下后退按钮时,此代码将失败。我会欣赏任何额外的眼睛,并帮助我找到我的错误。 (或者更好的方法)

谢谢!

1 个答案:

答案 0 :(得分:0)

知道了。我想当我将值重新分配给我的NSMutableArray天和NSMutableDictionary groupsTickets时,它只会覆盖以前的值。

我在视图上执行发布会消失,现在可以正常工作。

如果还有更好的方法,我会对学习它感兴趣。