动态UIPickerView竞争条件?

时间:2014-01-24 17:57:02

标签: objective-c uipickerview race-condition uipickerviewdatasource

我有一个两级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”的索引)。

我想这是由竞争条件引起的,但我该如何解决呢?

1 个答案:

答案 0 :(得分:0)

如果组件表示具有三个成员(航空公司)的数组,并且该组件中的所选行是最后一个成员,然后将组件翻转以表示两个成员数组(水果),则会崩溃。 pickerview保留了这个变量(selectedrowincomponent:x),现在想要在两个成员数组上表示成员#2(只有成员#0-1) - > NSRangeException。您需要更改该组件中的selectedRow,然后再将其重新加载到另一个数组中。

我个人不喜欢使用一个选择器来做两件事,这很麻烦IMHO只是为每个编写一个不同的类作为委托/ dataSource,一个可以是另一个的子类,然后根据需要延迟加载em