2016-09-14 2 views
0

모든 검사에도 불구하고이 루프는 빈 배열 메시지에서 인덱스를 벗어나는 인덱스를 제공합니다. 나는 그것이 if 문을 검사하기 위해 if 문을 설정했기 때문에 색인이 범위를 벗어나지 않았 음을 알고 있지만 여전히 충돌합니다. 또한 코드를 편집하여 명시 적 인덱스 (예 : array [0] ...)가 발생해도 응용 프로그램이 충돌하지 않고 배열이 비어있는 경우 의미가 없습니다. 어떤 아이디어가 이것을 일으킬 수 있습니까?ios : 비어있는 배열의 인덱스가 범위를 벗어남

while을 사용하여 왜 배열을 반복하지 않는지에 관해서는 for가 동일한 문제를 일으켰으므로 색인을 직접 명시 적으로 수행하려고했지만 여전히 응용 프로그램이 충돌합니다.

while(index < self.representatives.count - 1){ 
     if(self.representatives.count > 0){ 
      self.api.getPoliticianContactInfo(self.representatives[8].candidateId!, completion: { (result, id) in 
        print(result[0].value 
        print(id) 
        print("The index is: \(index)") 
        self.representatives[index].contactInfo = result 
        self.api.getPoliticianPhoto(id, completion: { (image) in 
         self.representatives[index].photo = image 
         print(self.representatives[index].photo) 
      }) 
     } 
     index+=1 
    } 
+0

질문을 수정하여 실제 질문에 * 코드를 포함 시키십시오. * – Paulw11

+0

어레이에 충돌이 발생하지 않도록 'self.representives [8]'에 8 개 이상의 요소가 있습니까? –

+0

9 개의 요소가 있으므로 8을 넣어도 충돌이 발생하지 않습니다. –

답변

0

이벤트가 발생하는 순서를 명심하십시오. 코드 구조는 다음과 같습니다.

while(index < self.representatives.count - 1){ // (1) 
    if(self.representatives.count > 0){ 
     self.api.getPoliticianContactInfo(self.representatives[8].candidateId!, completion: { (result, id) in 
      // completion handler // (3) 
     }) 
    } 
    index+=1 // (2) 
} 

나는 주요 단계에 번호를 매겼습니다. 그래서 루프가 실행됩니다 : 인덱스가 최고 한계에 도달 할 때까지 내 번호는 1, 2, 1, 2, 1, 2 ...입니다. 그런 다음, 그 다음에 만 루프를 통과하는 각 패스에 대해 3, 3, 3, 3, 3으로 시작합니다.

3은 비동기 API에서 완료 핸들러이기 때문입니다. 지연되었습니다. 나머지 코드는 기다리지 않고 코드 나머지 부분을 즉시 실행 한 다음, 준비가 완료되면 완료 핸들러가 작동합니다.

이것은 index이 무엇인지, 어떤 순서로 진행되고 있는지, 완료 처리기의 반복이 어떤 순서로 발생했는지에 대한 가정을 부정확하게 만드는 원인 일 가능성이 큽니다.

+0

그러면 주 스레드에서 코드를 실행해야합니까? 나는 옳은 행동이 아닌 것처럼 느껴지지만 나는 아이디어가 없다. 방법으로 응답 주셔서 감사합니다. –

+0

@BobFlanders -'if' 문 안에 지역 변수가 있습니다. 이것은'index'의 현재 값입니다. 그런 다음 완료 핸들러 내에서 새 로컬 변수를 사용하십시오. – Rob

+0

비동기 코드가 실행되는 동안 확실히 차단하면 안됩니다. 그것은 무엇을 해야하는지의 정반대입니다. 필자는 이런 식으로 코드를 작성하면 안된다. 수행 할 비동기 작업이있을 때 단순히 루프 할 수 없습니다. 가장 가까운 완성 처리기의 마지막 단계로 다음 절차를 시작할 수 있습니다. 너는 몇몇 NSOperations을 일렬로 세울 수 있었다. 루핑에 의존하지 않는 무언가를 할 수 있습니다. – matt

0

이 시나리오에서는 인덱스를 사용할 필요가 없으며 코드가 비동기 적으로 실행되고 배열 크기에 대한 가정도 도움이되지 않습니다.

당신은 당신의 representatives 배열에 열거을 사용할 수 있습니다 : 루프가 representatives 배열이 바로 당신이 데이터로 업데이트되지 않습니다 완료 후 수 있도록 네트워크 작업이 여전히 비동기 적으로 실행됩니다

for representative in self.representatives { 
    if let candidateId = representative.candidateId { 
     self.api.getPoliticianContactInfo(candidateId, completion: { (result, id) in 
      if !result.isEmpty { 
       print(result[0].value) 
       print(id) 
       representive.contactInfo = result 
       self.api.getPoliticianPhoto(id, completion: { (image) in 
        representative.photo = image 
        print(representatives.photo) 
       }) 
      } 
     }) 
    } 
} 

하는 것으로 가져 오기.

네트워크 작업이 완료되었을 때 코드를 실행해야한다면 dispatch_group을 사용할 수 있습니다.