1

私がやろうとしているのは、@synchronizedディレクティブを使用して、シングルトン オブジェクトが一度に複数のスレッドからアクセスされないようにすることです。また、オブジェクトへの変更を失わないようにできる限り努力することが非常に重要であるため、そのシングルトン オブジェクトが変更されるたびにディスクに書き込むことで、そのオブジェクトを永続的に保存したいと考えています。

多くの人がそうしないでくださいと言うかもしれません。時間がかかりすぎます。それは良い習慣ではありません、など。はい、私はそれを認識しています。これはむしろ「どうなるか」です。質問。

そのため、シングルトン オブジェクトを変更するときはいつでも、変更コードを@synchronizedブロック内に配置してから、オブジェクトをディスクに書き込みます。私が考えていたdispatch_asyncのは、次のように別のスレッドでオブジェクトの書き込みを行うために使用することでした:

//singleton object
id dataStructure;

@synchronized(lockObject)
    {
        //code that modifies singleton object
        //not important

        //sharedFileQueue is a SERIAL queue
        dispatch_async([self sharedFileQueue], ^(void){
            NSError * err;

            NSData * plist = [NSPropertyListSerialization dataWithPropertyList:dataStructure
                                                      format:NSPropertyListBinaryFormat_v1_0
                                                      options:0 error:&err];

            //url to somewhere
            NSURL * url;
            BOOL success = [plist writeToURL:url atomically:YES];
        });

    }

@synchronizedそのため、一度にそのコード ブロックを実行できるスレッドは 1 つだけであると理解しています。私の理解dispatch_asyncは少し曖昧ですが、これはブロックをディスパッチキューに送信して非同期に実行し、すぐに戻ると思います。これは、ブロックがまだディスクに書き込まれている@synchronized間に別のスレッドがブロックを通過した場合、別のブロックを送信して実行し、新しく変更されたものをディスクに書き込むだけですが、最初のブロックがディスクに書き込まれるまで開始されないことを意味します。dataStructuredataStructuredataStructure

私はこれについて正しく考えていますか?また、設定はアトミックに変更されますYESか、NOまたはディスパッチキューのシリアル化により、複数のスレッドがこのファイルに同時に書き込まれないことが保証されますか?

ありがとうございました!

4

2 に答える 2

0

少なくとも、ロック オブジェクトへの書き込みを同期する必要があります。これは、非同期ブロックが のコンテキスト外で実行されるため@synchronized{ ... }です。これは、書き込み中に他の何かがデータを変更する可能性があり、論理的な不整合につながる可能性があることを意味します。

また、オブジェクトが最後に書き込まれてから変更されているかどうかを確認するメカニズムも必要になるでしょう。そうしないと、不要な IO 操作を行っていることに気付くでしょう。例えば

  • スレッド 1 はオブジェクトを変更し、書き込みをキューに入れます。
  • スレッド 2 はオブジェクトを変更し、書き込みをキューに入れます。
  • スレッド 1 の書き込みは、スレッド 1 とスレッド 2 からの mod を保存します
  • スレッド 2 の書き込みは、スレッド 1 とスレッド 2 からの mod を保存します (これは最後のステップと同じです)。
于 2014-07-03T08:56:37.930 に答える
0

https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

ディスパッチ キュー自体はスレッド セーフです。つまり、最初にロックを取得したり、キューへのアクセスを同期したりすることなく、システム上の任意のスレッドからディスパッチ キューにタスクを送信できます。

//singleton object
id dataStructure;

@synchronized(lockObject)
{
    //code that modifies singleton object
    //not important

    id dataStructureToWrite = [dataStructure copy];
    //sharedFileQueue is a SERIAL queue
    dispatch_async([self sharedFileQueue], ^(void){
        NSError * err;

        NSData * plist = [NSPropertyListSerialization dataWithPropertyList:dataStructureToWrite
                                                                    format:NSPropertyListBinaryFormat_v1_0
                                                                   options:0 error:&err];

        //url to somewhere
        NSURL * url;
        BOOL success = [plist writeToURL:url atomically:YES];
    });

}
于 2014-07-03T08:52:27.123 に答える