Я работаю с ViewController, который делегирует & datasources 2 разных табличных представления. в соответствии с тем, что пользователь хочет видеть (переключение происходит с «touchesBegan» для определенных областей в представлении.чередовать 2 приложения UITableViews freeze
ViewController является одним из 3 subcontrollers из вкладок приложения.
Чередование между tableviews работает только плавник . я получить правильные данные, расположение и т.д., и я могу переключаться между ними так часто, как я хочу.
первый TableView не содержит сложных данных, поэтому он будет загружен в течение нескольких миллисекунд.
второй tableview2 содержит данные, которые загружаются примерно 2-3 секунды (в зависимости от суммы сущностей в coredata). пока эти данные загружаются & tableview2 перерисовывает, я показываю MBProgressHUD. это тоже работает.
Проблема: если я взаимодействовать с tabbarcontroller в то время как table2 загружается & ИЛС вращается, приложение «зависает» ИЛС работает infinitly долго и любой userinteractino отключен. а также щелкнутая вкладка не откроется.
КОД: touchesBegan Функция
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
if (isLoadingAllMonth) {
return;
}
[[MBProgressHUD HUDForView:self.view]removeFromSuperview];
UITouch *touch = [[event allTouches]anyObject];
int viewTag = touch.view.tag; // 1 for thisMonth, 2 for allMonth
if (viewTag == 1) {
[allMonthButtonView setAlpha:.8];
[thisMonthButtonView setAlpha:1];
if (allMonthIsActive == NO) {
return;
}
else{
[self reloadThisMonth];
[allMonthTable removeFromSuperview];
[self.view addSubview:thisMonthTable];
allMonthIsActive = NO;
}
}
else if(viewTag == 2){
if (!allMonthIsActive) {
allMonthIsActive = YES;
if (isLoadingAllMonth) {
return;
}
[self.view addSubview:HUD];
[allMonthTable setFrame:CGRectMake(4, 64, 312, 343)];
[allMonthTable setBackgroundColor:[self grayColor]];
[self.view addSubview:allMonthTable];
HUD = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
isLoadingAllMonth = YES;
[self reloadAllMonth];
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self.allMonthTable reloadData]; // Or reload tableView
[HUD hide:YES];
});
});
}
}
}
КОД: reloadAllMonth
-(void)reloadAllMonth{
UIFont *titleFont = [UIFont fontWithName:@"Cochin" size:14.0];
UIFont *detailFont = [UIFont fontWithName:@"Cochin" size:18.0];
[[MBProgressHUD HUDForView:self.view] setLabelFont:titleFont];
[[MBProgressHUD HUDForView:self.view] setDetailsLabelFont:detailFont];
[[MBProgressHUD HUDForView:self.view] setLabelText:@"Please wait"];
[[MBProgressHUD HUDForView:self.view] setDetailsLabelText:@"Cleaning Cache"];
if (allMonthData.count != 0) {
for (NSMutableArray *arr in allMonthData) {
[arr removeAllObjects];
}
[allMonthData removeAllObjects];
for (NSMutableArray *arr in allMonthDataNumbers) {
[arr removeAllObjects];
}
[allMonthDataNumbers removeAllObjects];
}
NSDate *rootDate = [NSDate dateWithTimeIntervalSinceReferenceDate:(10*365*24*60*60)];
int rootMonth = [[dataHandler getMonthNumber:rootDate] intValue];
NSMutableArray *allExp = [[NSMutableArray alloc]init];
NSNumber *currentMonth = [dataHandler getMonthNumber:[NSDate date]];
NSMutableArray *temp = [[NSMutableArray alloc]init ];
NSNumber *tempMonth = [NSNumber numberWithInt:(currentMonth.intValue+1)];
[temp removeAllObjects];
[[MBProgressHUD HUDForView:self.view] setDetailsLabelText:@"Updating Data..."];
while (tempMonth.intValue > rootMonth) {
tempMonth = [NSNumber numberWithInt:(tempMonth.intValue-1)];
temp = [NSMutableArray arrayWithArray:[dataHandler fetchAllExpensesForMonth:tempMonth]] ;
if (temp.count != 0) {
[allExp addObject:temp];
}
}
allMonthData = allExp;
if (!allMonthDataNumbers) {
allMonthDataNumbers = [[NSMutableArray alloc]init];
}
[[MBProgressHUD HUDForView:self.view] setDetailsLabelText:@"Updating Balances..."];
for (NSArray *current in allMonthData) {
Expense *exp = [current objectAtIndex:0];
NSNumber *monthNumber = exp.month;
double budget = 0;
double spent = 0;
double balance = 0;
int count = 0;
double avgDayBal = 0;
for (Expense *exp in current) { // iterate this month
if (exp.expenseType.boolValue == 0) { // all day type expensees
spent = spent+exp.value.doubleValue;
count ++;
}
else if (exp.expenseType.boolValue == 1) {
budget = budget+exp.value.doubleValue;
}
}
balance = budget+spent;
avgDayBal = balance/[dataHandler numberOfDaysInMonthForMonth:monthNumber];
NSMutableArray *temp = [[NSMutableArray alloc]init];
[temp addObject:monthNumber];
[temp addObject:[NSNumber numberWithDouble:budget ]];
[temp addObject:[NSNumber numberWithDouble:spent ]];
[temp addObject:[NSNumber numberWithDouble:balance ]];
[temp addObject:[NSNumber numberWithInt:count ]];
[temp addObject:[NSNumber numberWithDouble:avgDayBal ]];
[allMonthDataNumbers addObject:temp];
}
NSNumber *day = [dataHandler getDayNumber:[NSDate date] ];
[[allMonthDataNumbers lastObject] addObject:day];
NSLog(@"We have %d month", [allMonthDataNumbers count]);
[[MBProgressHUD HUDForView:self.view] setDetailsLabelText:@"Updating Interface..."];
[allMonthTable reloadData];
isLoadingAllMonth = NO;
}
КОД: reloadThisMonth
-(void)reloadThisMonth{
[dataHandler updateData];
if (!tableData) {
tableData = [[NSMutableArray alloc]initWithCapacity:31];
}
for (NSMutableArray *temp in tableData) {
[temp removeAllObjects];
}
[tableData removeAllObjects];
for (int j = 0; j < 31; j++) { //fill with 31 empty mutuable arrays
NSMutableArray *tempArray = [[NSMutableArray alloc]init];
[tableData addObject:tempArray];
}
for (Expense *exp in dataHandler.allMonthExpenses) {
if (exp.expenseType.boolValue == 0) {
[[tableData objectAtIndex:(exp.day.intValue-1)]addObject:exp];
}
}
int countDayExp = 0;
for (NSMutableArray *arr in tableData) {
countDayExp = countDayExp + arr.count;
}
if (countDayExp == 0) {
hasDayExpenses = NO;
}
else{
hasDayExpenses = YES;
}
[thisMonthTable reloadData];
[thisMonthTable setBackgroundColor:[self grayColor]];
}
Кто-нибудь видит, где я ошибся? или что еще может быть проблемой? обе таблицы показывают штраф. если я не взаимодействую с приложением во время загрузки второго представления, все работает отлично. есть идеи?
обновление:
по-видимому, два потока сталкиваются, когда один и тот же grapping fetchroutine в то же время - вот скриншот из состояния паузы отладки в то время как приложение «висел». если я открою другую вкладку, которая нуждается в той же процедуре выборки, которую приложение зависает. если я отлаживаю & пауза в зависании, он показывает мне строку в процедуре выборки. его первый раз, когда я работаю с потоками - я был бы очень признателен некоторые материалы о том, как избежать этого столкновения:/
Извините, у вас нет времени, чтобы прочитать ваш код для правильного ответа, но это не похоже на то, что вы используете GCD. Если вы выбросите код, который загружает другую таблицу в отдельный поток, тогда основной поток может обрабатывать пользовательский интерфейс с приоритетом, и вы, вероятно, избавитесь от какого-либо отставания. –
Согласитесь с GCD. Мое предложение было бы попытаться изолировать причину. Возможно, создайте небольшой проект с этой сложной операцией и одной таблицей. Также не читали детали, но вполне вероятно, что длительная операция висит, чем ОС. – danh
Еще один намек: возьмите его в зависание и отложите. Вы можете найти ошибку сразу. – danh