我正在制作一个简单的应用程序进行一些计算。其中一些计算相当复杂,因此可能需要一段时间才能得到结果。我正在使用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变得没有响应,活动指示器没有显示
答案 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)
建议:
所以,像这样:
[[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调用需要在主线程上。
在