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 보고서에 따라 가지고 있었다.

self.data [row1] [row2]에 액세스하기 전에 row1과 row2의 유효성을 검사하고 실패한 경우 내 서버로 보내려면 몇 가지 코드를 추가하십시오. [pickerView selectedRowInComponent : 0] 값이 잘못된 것 같습니다. 예를 들어 사용자가 첫 번째 구성 요소를 "fruit"에서 "airlines"로 변경하고 두 번째 구성 요소에서 일부 항목을 선택하면 selectedRowInComponent : 0 값은 여전히 ​​0 ("fruit"의 인덱스) 일 수 있습니다.

이것이 경쟁 조건으로 인한 것 같지만 어떻게 해결할 수 있습니까?

답변

0

구성 요소가 세 명의 멤버 (항공사)로 구성된 배열을 나타내며 해당 구성 요소의 선택된 행이 마지막 멤버 인 경우 구성 요소를 뒤집어 두 멤버 배열 (과일)을 나타낼 때 충돌이 발생합니다. pickerview는이 변수 (selectedrowincomponent : x)를 보유하고 있으며 두 멤버 배열 (멤버 # 0-1 만 있음) -> NSRangeException에서 멤버 # 2를 나타 내기를 원합니다. 해당 구성 요소의 selectedRow를 다시로드하기 전에 다른 배열로 바꾸기 전에이를 변경해야합니다.

개인적으로 두 가지 작업을 수행 할 때 하나의 선택기를 사용하는 것이 좋지 않습니다. 이건 지저분한 것일뿐입니다. 다른 클래스를 작성하여 위임 할 수 있습니다./dataSource 각각 하나는 다른 클래스의 서브 클래스가 될 수 있고 필요에 따라 게으름로드.

+0

실제로 2 레벨 카테고리 선택을하고있었습니다. – benck

+0

방금 ​​솔루션을 사용하여이 문제를 해결했습니다. http://stackoverflow.com/questions/18544600/uipickerview-crashes-app-when-user-is-spinning-components-at-the-same-time 그러나 감사합니다. 흠뻑. :) – benck

+0

해결책이 있다는 것을 기쁘게 생각합니다. 내 대답은 실제로 같은 답변의 덜 자세한 반복 FYI, 어떻게 한판 승부가 동의 :) – Jef