2016-05-31 4 views
0

안녕하세요, 완료 블록 내에서 외부 참조 변수에 할당 된 값의 범위가 혼동스러워합니다. 예를 들어 아래 코드에서 operationError 및 savedRecords 값은 완료 블록 외부에서 유지됩니다.블록 내에 값이 할당 된 참조 변수

func applyLocalChangesToServer(insertedOrUpdatedCKRecords:Array<CKRecord>,deletedCKRecordIDs:Array<CKRecordID>) throws 
    { 
     var savedRecords:[CKRecord]? 
     var conflictedRecords:[CKRecord] = [CKRecord]() 
     var removeRecords:[CKRecord] = [CKRecord]() 
     var operationError : NSError? 

     let ckModifyRecordsOperation = CKModifyRecordsOperation(recordsToSave:insertedOrUpdatedCKRecords, recordIDsToDelete: deletedCKRecordIDs); 
     ckModifyRecordsOperation.atomic = true 
     ckModifyRecordsOperation.modifyRecordsCompletionBlock = ({(savedRecords1,deletedRecordIDs1,error)->Void in 

      operationError = error 

      if error == nil 
      { 
       wasSuccessful = true 
       savedRecords = savedRecords1 
      } 
      else 
      { 
       wasSuccessful = false 
       savedRecords = nil 
       errorCKS = self.handleError(error!) 
      } 

     }) 
     ckModifyRecordsOperation.perRecordCompletionBlock = ({(ckRecord,error)->Void in 

      if error != nil 
      { 
       if error!.code == CKErrorCode.ServerRecordChanged.rawValue 
       { 
        conflictedRecords.append(ckRecord!) 
       } 
      } 

     }) 

     self.operationQueue?.addOperation(ckModifyRecordsOperation) 
     self.operationQueue?.waitUntilAllOperationsAreFinished() 

     if conflictedRecords.count > 0 
     { 
      //Do work here 

     } 
     else if operationError != nil //Other then the partial error 
     { 
      throw operationError 
     } 

} 

참고 : func applyLocalChangesToServer가 오류를 발생시키고 while 루프 내에 있기 때문에 operationError를 할당해야합니다.

+0

왜 차단하고 대기 중입니까? 완료 블록에서 다른 함수를 호출하는 것이 어떻습니까? – Wain

+0

귀하의 가정은 정확합니다. 인클로저 범위에서 무시 된 이러한 변수는 완료 핸들러가 수행 된 후에 수정됩니다. 따라서 코드는 예상대로 작동해야합니다. –

+0

하나의 관찰 - self.operationQueue는 메소드 호출 전에 설정되어야합니다. 큐를 설정하지 않은 경우 코드를 추가하고 throw하는 것이 좋습니다. –

답변

0

귀하의 가정은 정확합니다. 인클로저 범위에서 무시 된 이러한 변수는 완료 핸들러가 수행 된 후에 수정됩니다. 따라서 코드는 예상대로 작동해야합니다.

또한 다음 사용할 수 있습니다

ckModifyRecordsOperation.main() 

대신 :

self.operationQueue?.addOperation(ckModifyRecordsOperation) 
self.operationQueue?.waitUntilAllOperationsAreFinished() 

그것이 도움이되기를 바랍니다.

+0

@ignor 내가 가진 혼란은 operation의 수명 시간에 관한 것이었다. 오류 변수는 완성 처리기 안에 할당되어 있기 때문에 어떻게 든 얻을 수있는 기회가된다. 즉, operationError = error가 클로저가 오류 수명을 처리하고 오류 메시지가 표시되고 operationError가 nil을 가리킬 수있는 경우 오류 변수를 가리킨다 고 가정합니다. 죄송 합니다만 바보 같은 질문이지만 여전히 폐쇄를위한 메모리 관리에 대해 혼란 스럽습니다 – user3519594

+0

@ user3519594 오류 객체의 유형이 '참조'유형이면 Swift의 참조가 기본적으로 '강'입니다. 즉, 'error'를 'operationError'에 할당하면 오류 객체 참조 카운터가 유지됩니다. 그래서 오류 객체는'operationError'가'nil'으로 설정되거나 범위가 끝날 때까지 할당 해제되지 않습니다 -'applyLocalChangesToServer()'가 수행됩니다. 에러 객체의 타입이'value' 타입이라면'operationError'는 에러 객체의 복사본을 가지고 있으므로 초기 에러 객체의 수명은 당신에게 영향을주지 않습니다. –

관련 문제