2016-05-31 10 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を設定する必要があります。キューが設定されていない場合は、コードをチェックインしてスローすることをお勧めします。 –

答えて

0

想定されているとおり、エンクロージャスコープ内で拒否されたこれらの変数は、完了ハンドラの実行後に変更されます。したがって、コードは期待どおりに動作するはずです。

また、あなたが使用することができます以下

ckModifyRecordsOperation.main() 

の代わり:

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

はそれがお役に立てば幸いです。

+0

@ignor私が持っていた混乱は、operationRear変数の寿命についてでした。これは、完了ハンドラの中に割り当てられているので、何らかの理由で何も得られない可能性があります。つまり、operationError = errorは、クロージャがエラーの生存期間を処理し、nillされる可能性があり、operationErrorがnilを指す場合、エラー変数をポイントします。申し訳ありませんが、愚かな質問ですが、閉鎖のためのメモリ管理についてまだ混乱しています – user3519594

+0

@ user3519594エラーオブジェクトの型が '参照 '型であれば、Swiftのリファレンスはデフォルトで'強い 'ですので、あなたは良いです。これは、エラーオブジェクト参照カウンタが保持されているときに、 'error'を' operationError'に代入すると意味します。したがって、 'operationError'が' nil'にセットされるか、そのスコープが終了するまでエラーオブジェクトは割り当て解除されません。 'applyLocalChangesToServer()'が実行されます。エラーオブジェクトの型が 'value'型の場合、' operationError'にはエラーオブジェクトのコピーがあるので、初期エラーオブジェクトの有効期間はコピーに影響しません。 –

関連する問題