3

我有用於裝載所述的UITableView此代碼:的UITableView reloadData EXC_BAD_ACESS代碼= 2

- (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

或呼叫

enter image description here

我希望這可以幫助。

編輯:

還沒有從NSZombies幫助。在Xcode中運行它(使用NSZombies)我得到了同樣的錯誤沒有輸出,用殭屍配置文件分析它沒有消息,應用程序崩潰。

編輯:

此錯誤是從章節標題來了,因爲當我註釋掉那些部分我不再得到的錯誤。我的章節標題實施有什麼不正確?

編輯:

這是_headers如何在DirectoryViewController.h聲明:

@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; 
} 
+0

該錯誤通常是因爲試圖訪問一個釋放對象而發生的。你應該確保你的所有對象都有強大的指針(比如_people和_headers)。 – rdelmar

+0

你是如何分配'_people' – samfisher

+0

@samfisher'_People = [NSMutableArray的新]' – carloabelli

回答

4

爲了避免內存問題,您應該創建對象並使用屬性訪問器方法引用對象。

@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)財產(retainstrong模擬):

- (NSMutableArray *)headers { 

    return _headers; 
} 

- (void)setHeaders:(NSMutableArray *)headers { 

    [_headers autorelease]; 
    _headers = [headers retain]; 
} 

如果使用self.符號在一個對象的引用計數的ARC環境跟蹤會自動完成。

你可以找到更多關於屬性here的信息。

編輯:

這似乎是在框架中的錯誤。檢查這個answer

+0

一個快速最後半相關的問題。通過object.var和[object var]/[object setVar]訪問和設置對象是否有區別。或者兩者都調用相同的方法? – carloabelli

+0

兩種變體都是相同的。只是新舊記法風格。 – Numeral

+0

看來我批准你提前回答。我希望你給我50分後,你仍然會有興趣:)。我曾嘗試過這一次,它似乎工作,但現在問題再次發生。我將編輯問題中的代碼以反映我現在擁有的內容。 – carloabelli

-1

我認爲這是死機由於自動釋放的TableView對象,「_People」數組或「_headers」陣。你必須做的第一件事是記錄它的值以檢查它是否已經發布的對象。 如果是這樣你可以使用

[_people retain]; 

[_headers retain]; 

[tableviewObject retain]; 

避免自動釋放。

+1

保留方法已棄用,請向我提供未棄用的代碼。 – carloabelli

+0

究竟是什麼導致了這個問題,爲什麼autorelease不能在這種情況下工作。 – carloabelli

0

第二個是因爲由於自動釋放,你應該使用的NSLog()檢查值,然後你可以找到解決方案非常easliy.Get在不同的階段或者不同的方法

+0

NSLogging時,一切看起來都很好。我現在在返回sectionIndexTitles數組的過程中或之後得到代碼= 2,而不是代碼= 1。所以我需要先將NSMutableArray轉換爲NSArray,因爲我認爲它會自動投射,爲什麼它會在第一次而不是第二次? – carloabelli

0

每個值沒有看到您的更多的代碼,我的猜測是,雖然這些字符串對於標題數組是等同的,但您並沒有在sectionForIndexTitle中正確比較它們。

請記住indexOfObject只有在指向字符串的指針完全相同時纔會有效。具有相同值的兩個字符串不一定就夠了。

爲了安全起見,你可以嘗試:

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

但同樣,這是因爲我們沒有明確的深入瞭解_headers構造或者還有什麼在你的代碼是怎麼回事猜測。

+0

請看我對主要問題的最後評論。 – carloabelli

+0

sectionForSectionIndexTitle的返回索引不正確,除非您100%確定所有字母都包含在您的部分列表中。相反,您需要計算最近的相似部分。例如,如果您的標題包含「A」「C」和「F」,那麼當您傳遞「D」時,您需要返回1或2. – russellm

+0

此列表的索引列表是可以完成的標題列表。 – carloabelli