2013-07-30 1 views
1

웹 사이트에서 JSON 데이터를 다운로드하고 테이블보기로 표시하는 iOS 6 프로그램을 만들고 있습니다. 나는 마술사가 잘 작동하는 새로 고침 방법에 끌기를 추가했습니다. 내가 설정보기 컨트롤러 (secondViewController)에 가서 주소를 변경하면 모든 것이 작동합니다. 그런 다음 끌어 오기 메서드를 사용하여 내 tableView 다시로드됩니다. 하지만 주소를 변경 한 후 3 번 리로드하면 앱이 다운됩니다. 이 오류가 발생합니다 :reload 테이블보기 : indexPath가 재설정되지 않았습니다. ios 6

*** Terminating app due to uncaught exception 'NSRangeException', 
reason: '*** -[__NSArrayM objectAtIndex:]: index 10 beyond bounds for empty array' 
*** First throw call stack: 
(0x1ca1012 0x10dee7e 0x1c430b4 0x3084 0xdd8fb 0xdd9cf 0xc61bb 0xd6b4b 0x732dd 0x10f26b0 0x229dfc0 0x229233c 0x2292150 0x22100bc 0x2211227 0x22bb333 0x22bb75f 0x1c60376 0x1c5fe06 0x1c47a82 0x1c46f44 0x1c46e1b 0x1bfb7e3 0x1bfb668 0x22ffc 0x1fbd 0x1ee5) 
libc++abi.dylib: terminate called throwing an exception 

내가 뭘 잘못하고 있니? 어떻게 문제를 해결할 수 있습니까? 당신의 도움을 주셔서 감사합니다 !

+0

테이블을로드하는 배열이 비어있어 앱이 충돌합니다. 배열의 값을 어디에서 변경하고 있습니까? 당신은 당신의 uitableview 델리게이트의 코드를 좀 더 넣어야한다. – Rushi

+0

배열을 할당 했습니까? – Ajay

+0

문제는 내가 튜토리얼을 따라 갔고 그 도시 기능을 사용하여 실제로 어떻게 처리해야할지 모르겠다는 것입니다. 내가 한 유일한 일은 City * currentCity = [citiesArray objectAtIndex : indexPath.row]; . – jrock007

답변

0

중요한 디자인 고려 사항은 비동기 적으로 모델 retreiveData이 모델을 비동기 적으로 업데이트한다는 것입니다. 즉,이 과정에서 테이블 뷰와의 상호 작용이 실패 할 수 있습니다. 비동기 적으로 실제 citiesArray 자체를 업데이트하면 안됩니다. 해당 배열에 대한 업데이트는 주 큐에서 발생해야합니다.

에만 다음 기존 citiesArray를 교체하고 같은, reloadData 전화, 다시 메인 큐에 파견 코드에서, 다음 기존 citiesArray 접촉하지 retrieveData을 변경할 수 있지만 오히려 만들고 새로운 배열을 반환하고,해야 :

- (void)refresh:(UIRefreshControl *)refreshControl { 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

     NSArray *newCitiesArray = [self retreiveData]; 

     dispatch_async(dispatch_get_main_queue(), ^{ 

      if (newCitiesArray) { 

       // you presumably only want to reload the data if `retrieveData` was successful 

       citiesArray = newCitiesArray 
       [myTableView reloadData]; 
      } 

      [refreshControl endRefreshing]; 
     }); 
    }); 
} 

분명히,이도 retrieveData에 약간의 변화를 포함 할 것이다, 그러나 희망 그 자체 설명이다. 그렇지 않다면 해당 코드로 질문을 업데이트하십시오. 제안을 더 할 수 있습니다. 그러나 우리는 당신이 거기에서 일어날 필요가있는 변화를 이해하고 있다고 생각하기 때문에 거기에 갈 필요가 없습니다.

글로벌 큐를 실제로 사용할지 여부를 생각하고있는 것과 같은 다른 미묘한 문제도 있습니다 (예 : 이전 새로 고침 중에 새로 고침을 한 경우 정말로 서버와 동시에 두 개의 쿼리가 진행되기를 원합니다. 업데이트를 메인 큐에 다시 보내므로 크래시는 발생하지 않지만 비효율적입니다. 완료 할 순서가 보장되지는 않습니다. 또한 NSOperationQueue을 사용하여 이전 요청 취소를 허용하는 코드를 작성할 수 있습니다.

그러나이 모든 것은 약간 복잡하고 주요 문제 인 충돌에 대한 2 차 관심사입니다. 위에 설명 된대로 retrieveData 코드를 리팩토링하여 citiesArray을 만지지 않도록하려면이 문제를 해결해야합니다.

+0

정말 도움이 답변을 주셔서 감사하지만 여전히 문제가 : 줄 NSArray * newCitiesArray = [self retreiveData]; 나에게 오류를 준다 : 'void'타입의 표현식으로 'NS_Array * __ strong'을 초기화한다. 왜 그런 일이 일어날까요? – jrock007

+0

@ jrock007 이렇게하려면,'retrieveData'를'void' 리턴 타입에서 NSArray (또는 가변 배열을 사용한다면 NSMutableArray')로 변경해야합니다. 그리고 그 메소드가'citiesArray'를 사용하지 않고'retrieveData'에서 사용할 새로운 변수를 생성하고, 그 메소드의 끝에서 새로운 배열 객체를 리턴합니다 (또는'nil'을 리턴합니다). 네트워크 또는 JSON 구문 분석 오류가있는 경우). – Rob

+1

약간의 코드를 변경하여이 문제를 해결하는 방법을 찾았습니다 ... 감사합니다! 당신은 정말 많이 도와 줬어! – jrock007