2016-07-11 2 views
2

저는 IOS 애플리케이션 개발을 처음 접했습니다.함수가 완료 될 때까지 viewWillAppear가 완료되지 않게하는 방법

viewWillAppear의 작업이 끝날 때까지 작업을 중단하려고합니다. 어떻게해야합니까? 여기

은 viewWillAppear의 :

override func viewWillAppear(animated: Bool) { 
    super.viewWillAppear(true) 

    checkFacts() 

    if reset != 0 { 
     print("removing all bird facts") 
     birdFacts.removeAll() 
    } 
} 

func checkFacts() { 
    let date = getDate() 
    var x: Bool = true 
    var ind: Int = 0 
    print("count is ", birdFacts.count) 
    while ind < birdFacts.count { 
     print("accessing each bird fact in checkFacts") 
     let imageAsset: CKAsset = birdFacts[ind].valueForKey("birdPicture") as! CKAsset 
     let image = UIImage(contentsOfFile: imageAsset.fileURL.path!) 
     print(image) 
     if image == nil { 
      if (birdFacts[ind].valueForKey("sortingDate") != nil){ 
       print("replacing fact") 
       print("accessing the sortingDate of current fact in checkFacts") 
       let sdate = birdFacts[ind].valueForKey("sortingDate") as! NSNumber 
       replaceFact(sdate, index: ind) 
      } 
      /*else { 
       birdFacts.removeAll() 
       print("removing all bird facts") 
      }*/ 

     } 
     ind = ind + 1 
     print(ind) 
    } 
    self.saveFacts() 
    let y = checkRepeatingFacts() 
    if y { 
     print("removing all facts") 
     birdFacts.removeAll() 
     //allprevFacts(date, olddate: 0) 
    } 
} 

checkFacts 참조 2 개 다른 기능을하지만, 나는 그들이 (그들이 내가 틀리지하지만 만약 내가 그들을에 추가합니다)

+0

viewWillAppear 전에 완료해야하는 checkFacts입니까? –

+0

예, checkFacts는 먼저 완료해야합니다. – Alex

+0

viewWillAppear 함수가 끝나기 전에 완료됩니다 (checkFacts에서 호출되는 함수에서 비동기 작업이없는 경우). 그래서 내가 누락 된 것 같습니다. 원하지 않는다는 것을 의미합니까? checkFacts가 끝날 때까지 표시 할보기? –

답변

1

따라서 댓글을 기반으로 checkFacts는 비동기 iCloud 작업을 호출하고 있습니다. 비동기 iCloud 작업이 완료되지 않으면보기에서 관리 할 수없는 데이터가 null이됩니다.

viewWillAppear을 유지하는 것은이를 관리하는 방법이 아닙니다. 즉, 사용자 인터페이스가 지연되어 사용자를 괴롭 히게됩니다.

첫째,보기는 충돌없이 null 데이터를 관리 할 수 ​​있어야합니다. 이 문제를 해결할 때조차도 데이터가 나 빠지고 사용자가 충돌을 싫어하는 경우가있을 수 있습니다. 그래서 나는 그것을 고칠 것을 권합니다.

원본 문제를 해결하려면보기에 검사되지 않은 데이터가로드되도록합니다. 그런 다음 checkData 프로세스를 트리거하고 완료되면 NSNotification을 게시하십시오. 해당 알림에 대한보기를보고 해당 내용이있을 때 내용을 다시 그립니다. 선택적으로 사용자가 검사되지 않은 데이터와 상호 작용하지 못하도록하려면 적절한 컨트롤을 사용하지 않도록 설정하고 알림이 발생할 때까지 활동 표시기를 표시하십시오.

+0

그 덕분에, 제안 해 주셔서 감사합니다! – Alex

2
여기 관련성이 확실하지 않다

응용 프로그램의 실제 수명주기를 변경하거나 중지하는 대신 클로저을 사용해보십시오. Apple Documentation에 따르면

override func viewWillAppear(animated: Bool) { 
    super.viewWillAppear(true) 

    checkFacts(){ Void in 
     if self.reset != 0 { 
      print("removing all bird facts") 
      birdFacts.removeAll() 
     } 
    } 
} 

func checkFacts(block: (()->Void)? = nil) { 
    let date = getDate() 
    var x: Bool = true 
    var ind: Int = 0 
    print("count is ", birdFacts.count) 
    while ind < birdFacts.count { 
     print("accessing each bird fact in checkFacts") 
     let imageAsset: CKAsset = birdFacts[ind].valueForKey("birdPicture") as! CKAsset 
     let image = UIImage(contentsOfFile: imageAsset.fileURL.path!) 
     print(image) 
     if image == nil { 
      if (birdFacts[ind].valueForKey("sortingDate") != nil){ 
       print("replacing fact") 
       print("accessing the sortingDate of current fact in checkFacts") 
       let sdate = birdFacts[ind].valueForKey("sortingDate") as! NSNumber 
       replaceFact(sdate, index: ind) 
      } 
      /*else { 
       birdFacts.removeAll() 
       print("removing all bird facts") 
      }*/ 

     } 
     ind = ind + 1 
     print(ind) 
    } 
    self.saveFacts() 
    let y = checkRepeatingFacts() 
    if y { 
     print("removing all facts") 
     birdFacts.removeAll() 
     //allprevFacts(date, olddate: 0) 
    } 

    // CALL CODE IN CLOSURE LAST // 
    if let block = block { 
     block() 
    } 
} 

:

클로저 건네 사용자 코드에서 사용할 수있는 기능을 자체 포함 된 블록입니다.

클로저는 정의 된 컨텍스트에서 모든 상수 및 변수에 대한 참조를 캡처하고 저장할 수 있습니다.

그래서 checkFacts()를 정의 같이 func checkFacts(block: (()->Void)? = nil){...} 우리는 선택적 checkFacts() 함수 내에서 실행되는 코드 블록으로 전달할 수있다.

구문이 block: (()->Void)? = nil이면 void를 반환하는 코드 블록을 사용할 수 있지만 아무 것도 전달되지 않으면 block은 단순히 nil이됩니다. 이렇게하면 closure를 사용하거나 사용하지 않고 함수를 호출 할 수 있습니다. 사용하여

:

if let block = block { 
    block() 
} 

우리는 안전하게 block()를 호출 할 수 있습니다. blocknil으로 돌아 오면, 우리는 그것을 넘기고 아무 일도 없었던 것처럼 가장합니다. block이 아니고nil이면 우리는 그 안에 포함 된 코드를 실행할 수 있습니다.

checkFacts()에 클로저 코드를 전달할 수있는 한 가지 방법은 후행 폐쇄 방법입니다. 후행 폐쇄는 다음과 같습니다

checkFacts(){ Void in 
    if self.reset != 0 { 
     print("removing all bird facts") 
     birdFacts.removeAll() 
    } 
} 

편집 : 추가 구문 설명.

+0

이전에 블록으로 작업하지 않았기 때문에 구문을 설명해 주시겠습니까? – Alex

+0

@Alex 모든 것을 쉽게 이해할 수 있도록 희망하는 설명으로 답변을 업데이트했습니다. – ZGski

+0

오케이, 이제 더 이해가됩니다. 내가 겪고있는 문제는 checkFacts가 중복 사실을 찾아내는 것으로,이 사실로 인해 모든 사실을 삭제하고 클라우드에서 새 집합을 다시 다운로드하게됩니다. 그러나 tableView가 실행될 때 존재하지 않는 사실을 찾아 코드를 충돌시킵니다. 내가 당신의 코드를 시도했는데 그게 문제를 해결하지 못했다면, 내가해야 할 구체적인 것이 있습니까? – Alex

관련 문제