UITableView reloadData EXC_BAD_ACESS代码= 2

我有这个代码加载UITableView:

- (int)numberOfSectionsInTableView:(UITableView *)tableView { if (tableView == self.peopleTableView) return [self.people count]; else return [[[self.scheduleDays objectAtIndex:self.dayInt] periods] count]; } - (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (tableView == self.peopleTableView) return [[self.people objectAtIndex:section] count]; else return 1; } - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { if (tableView == self.peopleTableView) return [self.headers objectAtIndex:section]; else return [NSString stringWithFormat:@"%@ - %@", [[[[self.scheduleDays objectAtIndex:self.dayInt] periods] objectAtIndex:section] startTime], [[[[self.scheduleDays objectAtIndex:self.dayInt] periods] objectAtIndex:section] endTime]]; } - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { return self.headers; } - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { return index; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { if (tableView == self.peopleTableView) { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; if (cell == nil) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; Person *person = [[self.people objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]]; [[cell textLabel] setText:[NSString stringWithFormat:@"%@ %@", [person firstName], [person lastName]]]; return cell; } else { ScheduleTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"]; if (cell == nil) { cell = [[ScheduleTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"]; [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; } Period *period = [[[[[[self appDelegate] user] scheduleDays] objectAtIndex:self.dayInt] periods] objectAtIndex:[indexPath section]]; [[cell mainLabel] setText:[period desc]]; [[cell subtitleLabel1] setText:[period teacher]]; [[cell subtitleLabel2] setText:[period roomLocation]]; return cell; } } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (tableView == self.peopleTableView) { self.currentViewedPerson = [[self.people objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]]; [self loadPerson:self.currentViewedPerson]; [tableView deselectRowAtIndexPath:indexPath animated:YES]; } } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (tableView == self.scheduleTable) return 70; else return 44; } 

我使用方法调用[_tableView reloadData]来加载数据。 它第一次工作正常,但第二次失败, EXC_BAD_ACCESS code=2 。 为什么?

编辑:

似乎错误来自于调用

 #0 0x01b8c2a3 in TComponentFont::GetMinSideBearing(CGAffineTransform const&, bool) const () 

TComponentFont

或致电

在此处输入图像描述

我希望这有帮助。

编辑:

也没有NSZombies的帮助。 在Xcode(使用NSZombies)中运行它我得到相同的错误没有输出,使用僵尸配置文件分析它没有消息,应用程序只是崩溃。

编辑:

这个错误来自章节标题,因为当我注释掉那些部分时我不再收到错误。 我的章节标题实施有什么不正确之处?

编辑:

这是在DirectoryViewController.h中声明_headers方式:

 @property (strong, nonatomic) NSMutableArray *headers; 

如何填充标题(可能不是全部必需但……):

 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if (parser == self.peopleParser) { if ([elementName isEqualToString:@"People"]) { self.people = [NSMutableArray array]; self.headers = [NSMutableArray array]; } else if ([elementName isEqualToString:@"Person"]) { self.currentPerson = [Person new]; [self.currentPerson setPersonID:[attributeDict objectForKey:@"id"]]; } } else if (parser == self.scheduleParser) { if ([elementName isEqualToString:@"Schedule"]) self.scheduleDays = [NSMutableArray array]; else if ([elementName isEqualToString:@"Day"]) { NSEntityDescription *entity = [NSEntityDescription entityForName:@"ScheduleDay" inManagedObjectContext:[[self appDelegate] managedObjectContext]]; self.currentDay = [[ScheduleDay alloc] initWithEntity:entity insertIntoManagedObjectContext:nil]; } else if ([elementName isEqualToString:@"Course"]) { NSEntityDescription *entity = [NSEntityDescription entityForName:@"Period" inManagedObjectContext:[[self appDelegate] managedObjectContext]]; self.currentPeriod = [[Period alloc] initWithEntity:entity insertIntoManagedObjectContext:nil]; } } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { self.currentString = string; } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { if (parser == self.peopleParser) { if ([elementName isEqualToString:@"People"]) self.currentLetter = @""; else if ([elementName isEqualToString:@"Person"]) { if ([self.currentLetter isEqualToString:[[[self.currentPerson lastName] substringToIndex:1] uppercaseString]]) [[self.people lastObject] addObject:self.currentPerson]; else { [self.people addObject:[NSMutableArray array]]; [self.headers addObject:[[[self.currentPerson lastName] substringToIndex:1] uppercaseString]]; self.currentLetter = [[[self.currentPerson lastName] substringToIndex:1] uppercaseString]; [[self.people lastObject] addObject:self.currentPerson]; } } else if ([elementName isEqualToString:@"Last"]) [self.currentPerson setLastName:self.currentString]; else if ([elementName isEqualToString:@"First"]) [self.currentPerson setFirstName:self.currentString]; else if ([elementName isEqualToString:@"EmailAddress"]) [self.currentPerson setEmail:self.currentString]; else if ([elementName isEqualToString:@"PhoneCell"]) [self.currentPerson setCellPhone:self.currentString]; else if ([elementName isEqualToString:@"PhoneHome"]) [self.currentPerson setHomePhone:self.currentString]; else if ([elementName isEqualToString:@"GradYear"]) [self.currentPerson setGradYear:self.currentString]; else if ([elementName isEqualToString:@"StudentGrade"]) [self.currentPerson setGrade:self.currentString]; else if ([elementName isEqualToString:@"Street1"]) [self.currentPerson setStreet1:self.currentString]; else if ([elementName isEqualToString:@"Street2"]) [self.currentPerson setStreet2:self.currentString]; else if ([elementName isEqualToString:@"City"]) [self.currentPerson setCity:self.currentString]; else if ([elementName isEqualToString:@"State"]) [self.currentPerson setState:self.currentString]; else if ([elementName isEqualToString:@"Zip"]) [self.currentPerson setZip:self.currentString]; } else if (parser == self.scheduleParser) { if ([elementName isEqualToString:@"Course"]) [self.currentPeriod setDay:self.currentDay]; else if ([elementName isEqualToString:@"Day"]) [self.scheduleDays addObject:self.currentDay]; else if ([elementName isEqualToString:@"StartTime"]) [self.currentPeriod setStartTime:self.currentString]; else if ([elementName isEqualToString:@"EndTime"]) [self.currentPeriod setEndTime:self.currentString]; else if ([elementName isEqualToString:@"Description"]) [self.currentPeriod setDesc:self.currentString]; else if ([elementName isEqualToString:@"Location"]) [self.currentPeriod setRoomLocation:self.currentString]; else if ([elementName isEqualToString:@"Teacher"]) [self.currentPeriod setTeacher:self.currentString]; } self.currentString = @""; } - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { if ([parseError code] == 5) { self.people = [NSMutableArray array]; self.headers = [NSMutableArray array]; } else { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error!" message:[parseError description] delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; } } 

编辑:

调用reloadData位置:

 - (void)search { NSString *urlString = [LINK SETUP CODE GOES HERE] self.peopleParser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:urlString]]; self.peopleParser.delegate = self; if ([self.peopleParser parse] && [self.people count] > 0) { [self.peopleTableView reloadData]; [self.peopleTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; [self.view addSubview:self.peopleView]; } else { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No Results!" message:@"Your search returned no results. Try broadening your search." delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [alert show]; } [self.activityIndicator stopAnimating]; self.activityIndicator.hidden = YES; } 

为避免内存问题,您应该使用属性访问器方法创建对象并引用对象。

例如,您为headers mutable数组声明了属性:

 @property (strong, nonatomic) NSMutableArray *headers; 

然后你应该这样创建你的数组:

  self.headers = [NSMutableArray array]; 

并以这种方式引用您的数组:

 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { return [self.headers objectAtIndex:section]; } - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { return self.headers; } 

使用此语法可以为headers属性调用setter和getter方法(这些方法由Xcode自动生成)。

在非ARC环境中,对于(retain, nonatomic)属性调用这些方法是等效的( retain类似于strong ):

 - (NSMutableArray *)headers { return _headers; } - (void)setHeaders:(NSMutableArray *)headers { [_headers autorelease]; _headers = [headers retain]; } 

如果你使用self. ARC环境中的符号将自动跟踪对象的引用计数。

您可以在此处找到有关属性的更多信息。

编辑:

它似乎是框架中的一个错误。 检查这个答案

第二个是因为自动释放,你应该使用NSLog()检查值,然后你可以很容易地找到解决方案。在不同的阶段或不同的方法中获取每个值

在没有看到更多代码的情况下,我的猜测是虽然字符串对于标题数组是等效的,但是你并没有在sectionForIndexTitle中正确地比较它们。

请记住,只有指向字符串的指针完全相同时,indexOfObject才会起作用。 拥有两个具有相同值的字符串不一定足够。

为安全起见,您可以尝试:

 for (int i = 0; i < [_headers count]; ++i) { if ([_headers[i] isEqualToString title]) { return i; } } // error handling belongs here 

但同样,这是一个猜测,因为我们没有清楚地了解如何构建_headers或者代码中还有什么。

我认为这次崩溃是由于自动释放TableView对象,’_people’数组或’_headers’数组。 您要做的第一件事是记录其值以检查它是否是已发布的对象。 如果是这样,你可以使用

  [_people retain]; 

要么

  [_headers retain]; 

要么

  [tableviewObject retain]; 

避免自动释放。