0

У меня есть двухуровневый UIPickerView, который означает, что если пользователь выбирает первый компонент, второй компонент будет обновлять свои данные.динамическое состояние гонки UIPickerView?

Данные должны быть выглядеть следующим образом:

self.type = @[@"fruit", @"airlines"]; 
self.data = @[@[@"Apple", @"Orange"], @[@"Delta", @"United", @"American"]]; 

и источник данных делегат метода:

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { 
    return 2; 
} 

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { 
    if(component == 0){ 
     return self.data.count; 
    }else if(component == 1){ 
     NSInteger row1 = [pickerView selectedRowInComponent:0]; 
     return [self.data[row1] count]; 
    } 
} 


- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{ 
    if(component == 0){ 
     [pickerView reloadComponent:1]; 
    } 
    NSInteger row1 = [pickerView selectedRowInComponent:0]; 
    NSInteger row2 = [pickerView selectedRowInComponent:1]; 

    // here may crash, some time 
    NSLog(@"data: %@", self.data[row1][row2]); 
} 


- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{ 
    if(component == 0){ 
     return self.type[row]; 
    }else if(component == 1){ 
     NSInteger row1 = [pickerView selectedRowInComponent:0]; 
     // here may also crash 
     return self.data[row1][row]; 
    } 
} 

Есть несколько мест, которые могут привести к аварии (NSRangeException) в приведенном выше коде, как прокомментировал. Однако они редко случались. Я еще не получил эту катастрофу, но мои пользователи получили отчет Crashlytics.

Я добавляю несколько кодов для проверки строк1 и строки2 перед доступом к self.data [row1] [row2] и при отправке на мой сервер. Я обнаружил, что значение [pickerView selectedRowInComponent: 0] может быть некорректным. Например, когда пользователь меняет первый компонент с «фрукты» на «авиакомпании» и выбирает какой-то элемент во втором компоненте, значение selectedRowInComponent: 0 все равно может быть 0 (индекс «фрукты»).

Я предполагаю, что это вызвано состоянием гонки, но как я могу это решить?

ответ

0

Он будет разбиваться, если компонент представляет массив с тремя членами (авиалиниями). И выбранная строка в этом компоненте является последним членом, а затем вы переворачиваете компонент для представления двух элементов массива (фрукты). Элемент pickerview сохранил эту переменную (selectedrowincomponent: x) и теперь хочет представлять элемент # 2 в массиве из двух элементов (имеет только члены # 0-1) -> NSRangeException. Вам нужно изменить выбранный Row в этом компоненте, прежде чем перевернуть его в другой массив с перезагрузкой.

Мне лично не нравится использовать один сборщик, чтобы сделать две вещи, это грязно. ИМХО просто пишите другой класс, который должен быть делегатом/dataSource для каждого, один может быть подклассом другого, тогда ленивая загрузка em по мере необходимости

+0

Фактически я делал выбор категории двух уровней. – benck

+0

Я просто решил эту проблему с решением здесь: http://stackoverflow.com/questions/18544600/uipickerview-crashes-app-when-user-is-spinning-components-at-the-same-time Однако, спасибо очень. :) – benck

+0

Я рад, что у вас есть решение. Мой ответ на самом деле является менее подробным повторением того же ответа FYI, как бой принять :) – Jef

Смежные вопросы