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