0

现在我知道 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;
}

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

谢谢!

4

1 回答 1

0

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

我在视图上执行的发布将消失,它现在可以工作了。

不过,如果有更好的方法来做到这一点,我会有兴趣学习它。

于 2013-05-23T14:59:06.973 回答