2016-03-25 8 views
0

可能性のあるUIDocumentサブクラスを使用していますが、複数のスレッドから呼び出されるsaveToURLメソッドがあります。私ので、私はスレッドセーフにしたいラッパー関数でそれをカプセル化している:私は、保存操作自体はにロックを引き起こして、バックグラウンドスレッドで発生するので[self saveToURL:...]への呼び出しはすぐに復帰することを想定しています同期操作で@synchronizedを使用する

- (void)saveWithCompletionBlock:(void(^)(TransactionDocumentReturnCode status))completion { 
    @synchronized (self) { 
     [self saveToURL:[self fileURL] forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success){ 
      // Generate returncode depending on outcome of save operation 
      completion(returncode); 
     }]; 
    } 
} 

保存操作が完了する前に潜在的に解放されてください。だから、saveToURLの完了ブロックが呼び出されるまで、saveWithCompletionBlock:をブロックして他のスレッドをブロックする方法はありますか?

+0

これを実装する2つの方法については、この回答をご覧ください:http://stackoverflow.com/a/7649768/78496 – chedabob

+0

ありがとうございます@chedabob。 GCDまたはNSOperationQueueを使用すると、セーブ操作の完了ブロックが終了するまで、セーブラッパー関数への後続の呼び出しがブロックされますか? – mashers

答えて

0

私が考えた可能性のある解決策の1つは、保存操作が進行中かどうかを示すためにUIDocumentサブクラスにプロパティを追加し、そうであれば待機してから再試行することです。

- (void)saveWithCompletionBlock:(void(^)(TransactionDocumentReturnCode status))completion { 
    @synchronized(self){ 
     if (self.isSaving) { 
      [self performSelector:@selector(saveWithCompletionBlock:) withObject:completion afterDelay:1.0]; 
      return; 
     } 

     self.isSaving = YES; 
    } 

    [self saveToURL:[self fileURL] forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success){ 
     // Generate returncode depending on outcome of save operation 
     completion(returncode); 
     self.isSaving = NO; 
    }]; 
} 

これは十分またはマルチ良いと考えられる場合、私は知らない。@synchronizeにこのプロパティのチェックや設定をラップすると同時に偽として値を読み取ると、彼らは文書を保存することができます信じからの二つのスレッドを防ぐ必要があります - スレッドの練習。

+0

上記の解決策はうまくいくようです。 '[self performSelector:...] 'の前に' [NSObject cancelPreviousPerformRequestsWithTarget:self] 'への呼び出しを追加すると、アプリケーションは最初の保存操作の終了まで待機し、完了後にもう一度保存します。私はまだこのソリューションに関するフィードバックを歓迎します。 – mashers