我有一个两级UIPickerView,这意味着如果用户选择第一个组件,第二个组件将更新其数据。
数据应如下所示:
self.type = @[@"fruit", @"airlines"];
self.data = @[@[@"Apple", @"Orange"], @[@"Delta", @"United", @"American"]];
datasource和delegate方法:
- (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报告。
我在访问self.data [row1] [row2]之前添加了一些代码来验证row1和row2,如果失败则发送到我的服务器。我发现某些时候[pickerView selectedRowInComponent:0]的值可能不正确。例如,当用户将第一个组件从“fruit”更改为“airlines”并选择第二个组件中的某个项时,selectedRowInComponent:0的值可能仍为0(“fruit”的索引)。
我想这是由竞争条件引起的,但我该如何解决呢?
答案 0 :(得分:0)
如果组件表示具有三个成员(航空公司)的数组,并且该组件中的所选行是最后一个成员,然后将组件翻转以表示两个成员数组(水果),则会崩溃。 pickerview保留了这个变量(selectedrowincomponent:x),现在想要在两个成员数组上表示成员#2(只有成员#0-1) - > NSRangeException。您需要更改该组件中的selectedRow,然后再将其重新加载到另一个数组中。
我个人不喜欢使用一个选择器来做两件事,这很麻烦IMHO只是为每个编写一个不同的类作为委托/ dataSource,一个可以是另一个的子类,然后根据需要延迟加载em