2014-09-26 157 views
3

當我在tableView結束滾動之前給我的tableView一個很好的滑動並按下「返回」按鈕時,我的應用程序崩潰。我試過以下內容:當tableView仍在滾動時,popToRootViewController崩潰

- (void) closeViewController 
{ 
    [self killScroll]; 
    [self.navigationController popToRootViewControllerAnimated:YES]; 
    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

- (void)killScroll 
{ 
    CGPoint offset = sellersTableView.contentOffset; 
    [sellersTableView setContentOffset:offset animated:NO]; 
} 

這並沒有工作,同樣的崩潰。我不明白爲什麼,我得到的錯誤是:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UITableView dataSource must return a cell from tableView:cellForRowAtIndexPath:' 

因此,這意味着該的tableView仍請求單元都已經被釋放的時候。沒有意義。 然後我試過這個:

- (void) closeViewController 
{ 
    [self.navigationController popToRootViewControllerAnimated:YES]; 
    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

- (void)dealloc 
{ 
    sellersTableView.dataSource = nil; 
    sellersTableView.delegate = nil; 
    sellersTableView = nil; 
} 

給我同樣的錯誤。有任何想法嗎?

更新: 我的委託方法

創作

if (textField == addSellerTextField) { 
     sellersTableView = [[UITableView alloc] initWithFrame:CGRectMake(addSellerTextField.frame.origin.x + addSellerTextField.frame.size.width + 10, addSellerTextField.frame.origin.y - [self heightForTableView] + 35, 200, [self heightForTableView])]; 
     sellersTableView.delegate = self; 
     sellersTableView.dataSource = self; 
     sellersTableView.backgroundColor = [[UIColor grayColor] colorWithAlphaComponent:0.05]; 
     sellersTableView.separatorColor = [[UIColor grayColor] colorWithAlphaComponent:0.15]; 
     sellersTableView.rowHeight = 44; 
     sellersTableView.layer.opacity = 0; 
     [self.companyView addSubview:sellersTableView]; 
     [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{sellersTableView.layer.opacity = 1;} completion:nil]; 
    } 

的cellForRowAtIndexPath

if (tableView == sellersTableView) { 
     if (!cell) { 
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 
     } 
     cell.backgroundColor = [UIColor clearColor]; 
     if ([sellersArray count] > 0) { 
      cell.textLabel.text = [sellersArray objectAtIndex:indexPath.row]; 
     } else { 
      UILabel *noSellersYetLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, sellersTableView.frame.size.width, [self heightForTableView])]; 
      noSellersYetLabel.text = @"no sellers yet"; 
      noSellersYetLabel.textAlignment = NSTextAlignmentCenter; 
      noSellersYetLabel.textColor = [UIColor grayColor]; 
      [cell addSubview:noSellersYetLabel]; 
      sellersTableView.separatorStyle = UITableViewCellSeparatorStyleNone; 
     } 
    } 

去除

- (void) textFieldDidEndEditing:(UITextField *)textField 
{ 
    if (textField == addSellerTextField) { 
     [self updateSellers:textField]; 
    } 
} 
- (void)updateSellers:(UITextField *)textField 
{ 
    [textField resignFirstResponder]; 
    [self hideSellersTableView]; 
} 

- (void)hideSellersTableView 
{ 
    [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{sellersTableView.layer.opacity = 0;} completion:nil]; 
    sellersTableView.dataSource = nil; 
    sellersTableView.delegate = nil; 
    [sellersTableView removeFromSuperview]; 
    sellersTableView = nil; 
} 

解決方案 因此很明顯,把dataSource = nildelegate = niltextFieldDidEndEditing解決了這一問題。謝謝大家的答案!

+0

你能提供你的viewController一些額外的信息層次? – 2014-09-26 13:39:11

+0

檢查這是否可以幫助你http://stackoverflow.com/questions/19087867/ios-7-on-textfield-did-change-the-firstresponder-my-application-is-crashing – iOSdev 2014-09-26 13:41:54

回答

2

這是UITableView的奇怪行爲。解決此問題的最簡單方法是在您調用函數popToRootViewControllerAnimated之前將dataSourcedelegate屬性UITAbleView設置爲零。此外,您可以使用更常見的解決方案,並將將屬性設置爲零的代碼添加到-dealloc方法中。另外你不需要-killScroll方法。

經過短時間的研究,我意識到問題所在。這種不尋常的行爲出現在iOS 7中。其超級視圖保留的滾動視圖可能會在委託發佈後將消息發送給委託。這是由於-removeFromSuperview執行UIScrollView觸發器-setContentOffset:,並最終發送消息給代表。

+0

我曾嘗試設置'dataSource'並在結束前將「委託」改爲零,但我仍然遇到了崩潰。 Thx的信息btw :) – Yoko 2014-09-26 14:37:45

1

setContentOffset方法不會幫你,嘗試設置

sellersTableView.dataSource = nil; 

某處你viewWillDisappear方法。 這當然不是一個好習慣。

+0

試過這個,但沒有運氣。仍然崩潰與相同的錯誤。 Thx雖然! – Yoko 2014-09-26 14:39:29

0

我不認爲設置tableView(或它的委託)爲零是問題。您應該能夠單獨執行dismissViewControllerAnimated或popToRootViewController,而無需通過這種方式修改tableView。

所以這個問題很可能是由於同時調用這兩個方法(並且帶有animated = YES),並且這樣做要求您的viewController設置執行一些不自然的操作。

看起來像點擊一個「關閉」按鈕,你都彈出的UINavigationController,以及解散模態viewController

在這樣做時,您將忽略可能由navigationControllertopViewController表示的模式viewController(因此top vc持有對模態vc的引用)。並且您正試圖通過popToRootViewController方法調用來終止頂層vc。而且你正在使用animated = YES來完成這兩件事,這意味着它們需要一些時間才能完成,並且你無法確定每次完成的時間(即不能確定何時調用dealloc)。

根據你的需要,你可以做幾件事情之一。

考慮添加一個委託屬性到你的模態vc。關閉模態vc,並在模態vc的completionBlock中告訴其代表它已完成解散。在這一點上,調用popToRootViewController(因爲在這一點上,你可以確定模式已經消失,滾動沒有中斷)。

如果它是你的navController,它是以模態方式呈現的,那麼以相反的順序進行操作。通知代表已完成流行操作,然後進行模式解僱。

+0

我刪除了'[self dismissViewControllerAnimated:YES completion:nil];',那是我的錯誤。但除此之外,錯誤仍然存​​在,並導致我的應用程序崩潰。 Thx雖然答案! – Yoko 2014-09-26 14:41:39

2

就在dealloc方法的開頭添加以下行:

sellersTableView.delegate = nil; 
sellersTableView.dataSource = nil; 

沒有必要使用黑客喜歡你killScroll方法。

另外,我看不出爲什麼你要打電話popToRootViewControllerdismissViewController。 如果您關閉嵌入在導航控制器中的視圖控制器,導航控制器本身以及所有包含的視圖控制器將被釋放。

在你的情況下,你只會有奇怪的動畫。

+0

嘗試了你的方法,但它仍然崩潰,同樣的錯誤。關於我的'popToRootViewController'&'dismissViewController',你是對的,那簡直是愚蠢的。 – Yoko 2014-09-26 14:35:02

+0

在這種情況下,請提供代理和數據源方法的代碼。 – hybridcattt 2014-09-27 17:23:15

1

更改您closeViewController像下面,看看作品

  • (無效)closeViewController

{

sellersTableView.dataSource = nil; 
sellersTableView.delegate = nil; 
[self.navigationController popToRootViewControllerAnimated:YES]; 
[self dismissViewControllerAnimated:YES completion:nil]; 

}

+0

Thx爲您的答案! Buuuuuut,嘗試了它,並得到相同的結果。 – Yoko 2014-09-26 20:17:45

+0

我在想的是你沒有提供sellersTableView到你的xib/storyboard的連接。 – 2014-09-26 20:34:16

+0

對不起,這是全部編碼。沒有xib或故事板... – Yoko 2014-09-27 01:00:24