私はブロックの大ファンですが、並行性のためにそれらを使用していません。少しグーグルした後、私はこのアイデアをつなぎ合わせて、学んだことをすべて1か所に隠しました。目標は、バックグラウンドでブロックを実行し、それが終了したら、別のブロック(UIViewアニメーションなど)を実行することです...
- (NSOperation *)executeBlock:(void (^)(void))block completion:(void (^)(BOOL finished))completion {
NSOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:block];
NSOperation *completionOperation = [NSBlockOperation blockOperationWithBlock:^{
completion(blockOperation.isFinished);
}];
[completionOperation addDependency:blockOperation];
[[NSOperationQueue mainQueue] addOperation:completionOperation];
NSOperationQueue *backgroundOperationQueue = [[NSOperationQueue alloc] init];
[backgroundOperationQueue addOperation:blockOperation];
return blockOperation;
}
- (void)testIt {
NSMutableString *string = [NSMutableString stringWithString:@"tea"];
NSString *otherString = @"for";
NSOperation *operation = [self executeBlock:^{
NSString *yetAnother = @"two";
[string appendFormat:@" %@ %@", otherString, yetAnother];
} completion:^(BOOL finished) {
// this logs "tea for two"
NSLog(@"%@", string);
}];
NSLog(@"keep this operation so we can cancel it: %@", operation);
}
私の質問は次のとおりです。
- 実行すると動作しますが、何かが足りません...隠された地雷ですか?キャンセルをテストしていませんが(長い操作を発明していないため)、それは機能するように見えますか?
- 完了ブロックで参照できるように、backgroundOperationの宣言を修飾する必要があるのではないかと心配しています。コンパイラは文句を言いませんが、そこに潜んでいる保持サイクルはありますか?
- 「文字列」がivarの場合、ブロックの実行中にKey-Valueでそれを観察するとどうなりますか?または、メインスレッドにタイマーを設定して、定期的にログに記録しますか?進捗状況を確認できますか?アトミックと宣言しますか?
- これが期待どおりに機能する場合は、すべての詳細を非表示にして同時実行を取得するための良い方法のようです。なぜAppleは私のためにこれを書かなかったのですか?重要なものが欠けていますか?
ありがとう。