Xcode NSRangeException 在第二次运行代码时
Posted
技术标签:
【中文标题】Xcode NSRangeException 在第二次运行代码时【英文标题】:Xcode NSRangeException on second run through of code 【发布时间】:2013-05-23 14:42:13 【问题描述】:现在我知道 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】:知道了。我想当我将值重新分配给我的 NSMutableArray 天和 NSMutableDictionary groupedTickets 时,它只会覆盖以前的值。
我在视图上执行的发布将消失,它现在可以工作了。
如果有更好的方法来做到这一点,我会有兴趣学习它。
【讨论】:
以上是关于Xcode NSRangeException 在第二次运行代码时的主要内容,如果未能解决你的问题,请参考以下文章
GHAssertThrowsSpecific 找不到类型 NSRangeException