コード全体で呼び出すことができるメソッドがあります。以下は非常に基本的な例です。コードは iPhone フォト ギャラリーから画像とファイルを処理し、メソッドの実行が完了すると処理済みとしてマークします。
@property (nonatomic, assign) dispatch_queue_t serialQueue;
....
-(void)processImages
{
dispatch_async(self.serialQueue, ^{
//block to process images
NSLog(@"In processImages");
....
NSLog(@"Done with processImages");
});
}
このメソッドが呼び出されるたびに、以下の出力が得られると思います...「In processImages」「Done with processImages」「In processImages」「Done with processImages」など...
しかし、私はいつも得ます
「In processImages」「In processImages」「Done with processImages」「Done with processImages」など...
シリアル キューは、最初のブロックが完了するまで待ってから開始すると考えていました。私には、メソッドを開始しているように見えますが、最初の呼び出しが終了する前に再度呼び出されて起動し、実際に連続して実行された場合、メソッドはそれらを知っているという事実のために通常は処理されない画像の複製を作成しますすでに処理されていました。たぶん、シリアル キューに関する私の理解は具体的ではありません。入力はありますか?ありがとうございました。
編集:以下のコンテキスト、これはブロックで起こっていることです...これが問題を引き起こす可能性がありますか???
@property (nonatomic, assign) dispatch_queue_t serialQueue;
....
-(void)processImages
{
dispatch_async(self.serialQueue, ^{
//library is a reference to ALAssetsLibrary object
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop)
{
....
//Process the photos here
}];
failureBlock:^(NSError *error) { NSLog(@"Error loading images from library");
}];
});
}
-(id)init
{
self = [super init];
if(self)
{
_serialQueue = dispatch_queue_create("com.image.queue",NULL);
}
return self;
}
このオブジェクトは一度だけ作成され、コードに基づいて二度と作成できないと私が知る限り...テストを実行して確認します。
更新 2: 何が起こっていると思いますか。同意/同意しない場合は、これについてコメントしてください....
明らかに私の主な問題は、このコードブロックが同時に実行されているように見え、シリアルで実行された場合に通常はこれを行わないときに、重複したエントリ (同じ写真を 2 回インポートする) を作成することです。写真が処理されると、「ダーティ」ビットが適用され、次にメソッドが呼び出されたときにこの画像がスキップされるようになりますが、これは行われず、一部の画像は 2 回処理されます。これは、その serialQueue 内で enumerategroupswithtypes: を使用して 2 番目のキューでオブジェクトを列挙していることが原因でしょうか?
- processImages を呼び出す
- enumerateObjects
- それ自体が非同期であるため、 enumerateObjects からすぐに戻ります
- processImages の呼び出しを終了する
enumerategroups はおそらくまだ実行されているため、processImages は実際には完了していませんが、enumerategroups が動作を完了する前にブロックの最後に到達するため、キューが完了したと見なされる可能性があります。これは私には可能性のように思えますか?