[self.tableView reloadData]上的EXC_BAD_ACCESS

时间:2012-03-23 10:22:10

标签: iphone objective-c ios uitableview exc-bad-access

我正在制作一个简单的应用程序进行一些计算。其中一些计算相当复杂,因此可能需要一段时间才能得到结果。我正在使用UITableView让用户输入值。然后在单击“计算”按钮后,我在其上创建了一个简单的UIView,并在其中放置了UIActivityIndicatorView,并将其放在屏幕中间。然后我在后台调用计算方法。一些代码:

    self.activityIndicatorView = [[UIView alloc]initWithFrame:CGRectMake(320/2 - 50, (480 - 64)/2 - 50, 100, 100)];
    self.activityIndicatorView.layer.cornerRadius = 10.0f;
    self.activityIndicatorView.backgroundColor = [UIColor colorWithRed:0. green:0. blue:0. alpha:0.7];
    UIActivityIndicatorView *actInd = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    actInd.frame = CGRectMake((100 - actInd.frame.size.width) / 2, (100 - actInd.frame.size.height) / 2, actInd.frame.size.width, actInd.frame.size.height);
    [actInd startAnimating];
    [self.activityIndicatorView addSubview:actInd];
    [self.activityIndicatorView bringSubviewToFront:actInd];
    [self.view addSubview:self.activityIndicatorView];
    [self.view bringSubviewToFront:self.activityIndicatorView];
    [self performSelectorInBackground:@selector(calculateAllThatShizzle) withObject:nil];

如你所见,这很简单。但是,如果键盘仍然可见,则当EXC_BAD_ACCESS方法中的[self.tableView reloadData]与日志中的-(void)calculateAllThatShizzle进行匹配时,它会崩溃(2012-03-23 11:06:32.418 MyApp[869:5c07] bool _WebTryThreadLock(bool), 0x6adb270: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now... 1 WebThreadLock 2 -[UITextRangeImpl isEmpty] 3 -[UITextRange(UITextSelectionAdditions) _isCaret] 4 -[UITextSelectionView setCaretBlinks:] 5 -[UIKeyboardImpl setCaretBlinks:] 6 -[UIKeyboardImpl setDelegate:force:] 7 -[UIKeyboardImpl setDelegate:] 8 -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:] 9 -[UIResponder _finishResignFirstResponder] 10 -[UIResponder resignFirstResponder] 11 -[UITextField resignFirstResponder] 12 -[UITableView reloadData] 13 -[ChildViewController calculateAllThatShizzle] 14 -[NSThread main] 15 __NSThread__main__ 16 _pthread_start 17 thread_start }:

[cell.rightTextField resignFirstResponder]

所以问题是它正在尝试从后台线程用键盘做一些事情。我已经尝试循环遍历单元格并调用-(void)reloadTableViewData { [self.tableView reloadData]; } -(void)calculateAllThatShizzle { //some code omitted - code that uses UIKit if ([dob timeIntervalSinceDate:calcDate]>0) { [errorButton setTitle:@"Calculation Date must be more than Date of Birth" forState:UIControlStateNormal]; errorButton.hidden = NO; [self.activityIndicatorView removeFromSuperview]; self.activityIndicatorView = nil; return; } [self performSelectorOnMainThread:@selector(reloadTableViewData) withObject:nil waitUntilDone:NO]; } ,但它没有帮助。我也尝试过使用

ELCTextfieldCell

但它也没有帮助。我正在使用EXC_BAD_ACCESS

任何帮助将不胜感激。

谢谢

P.S。我确实在reloadData上检查了一些关于{{1}}的其他问题,但它没有解决我遇到的问题

P.P.S。我也可以在主线程中运行计算,但是GUI变得没有响应,活动指示器没有显示

2 个答案:

答案 0 :(得分:2)

试试这段代码

for(int i=0;i<[tblViewData count];i++)
{
    if([[(ELCTextfieldCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]] rightTextField] isFirstResponder])
    {
        [[(ELCTextfieldCell *)[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]] rightTextField] resignFirstResponder];
    }
}

根据你做改变。

答案 1 :(得分:2)

建议:

  • 在调用calculateAllThatShizzle 之前使tableView成为第一个响应者,即强制当前的第一个响应者辞职,从而解雇他们的键盘
  • 然后在当前运行循环完成后将对calculateAllThatShizzle的调用推迟到,即确保解除键盘的代码在合适的时间运行

所以,像这样:

[[self tableView] becomeFirstReponder]; // will dismiss keyboard
[[self performSelector: @selector(startBackgroundStuff) withObject: nil afterDelay: 0.0];

然后在你的startBackgroundStuff中你可以输入:

[self performSelectorInBackground:@selector(calculateAllThatShizzle) withObject:nil];

在该方法中,您肯定要确保在主线程上调用reloadData方法。你做的方式看起来还不错。 。您还可以执行以下操作:

dispatch_async(dispatch_get_main_queue(), ^{
        [self reloadTableViewData];
    });

(我不知道一个人是否比另一个好,只是确切地说,确实可靠地运作。)

补充评论

在calculateAllThatShizzle中,你在某些条件下从后台进行UIKit调用,即[self.activityIndicatorView removeFromSuperview];这可能会导致崩溃。 UIKit调用需要在主线程上。