シナリオ:
- ユーザーがボタンをタップして、名簿の変更を要求します。
- この変更を開始するためのメソッドが呼び出され、アラートビューが表示されます。
アラートビューを表示し、UIの応答性を維持するために、dispatch_queueを使用しました。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_sync(dispatch_get_main_queue(), ^{ // Show the alert view }); });
以下を使用して、名簿の変更プロセスを開始します。
dispatch_async(modifyingAddressBookQueue, ^{});
ここで、いつでも(もちろん、アドレス帳を保存する前に)プロセスをキャンセルできるようにする機能をユーザーに提供したいと思います。そこで、彼がアラートシートのキャンセルボタンをタップしたときに、ディスパッチブロックにアクセスし、特定のBOOLを設定してプロセスを停止し、アドレス帳を元に戻したいと思います。
問題は、それができないということです!すべての変数は一度だけコピーされるため、ブロックにアクセスしてその中の変数を変更することはできません。実行中のブロック内の変数の変更は、ブロックには表示されません。
要約すると、UIイベントを使用して進行中の操作を停止するにはどうすればよいですか?
アップデート:
プロセスのコード:
- (void) startFixingModification {
_fixContacts = YES;
__block BOOL cancelled = NO;
dispatch_queue_t modifyingAddressBookQueue;
modifyingAddressBookQueue = dispatch_queue_create(sModifyingAddressBookQueueIdentifier,
NULL);
dispatch_async(modifyingAddressBookQueue, ^{
for (NSMutableDictionary *contactDictionary in _contactArray) {
if (!cancelled) {
break;
}
i = i + 1;
BOOL didFixContact = [self fixNumberInContactDictionary:contactDictionary];
if (!didFixContact) {
_fixedNumbers = _fixedNumbers - 1;
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_sync(dispatch_get_main_queue(), ^{
[self setAlertViewProgress:i];
});
});
}
});
cancelledPtr = &cancelled;
}
alertview(自分のlib)デリゲートのコード
- (void) alertViewProgressCancel:(ASAlertViewProgress *)alertView { // This is a private lib.
if (cancelledPtr)
{
NSLog(@"stopping");
*cancelledPtr = YES;
}
}
インターフェイスで、私は宣言します
BOOL* cancelledPtr;
アップデート2:
本当にイライラします!次のコードの場合
for (NSMutableDictionary *contactDictionary in _contactArray) {
NSLog(@"%d", _cancelModification);
if (_cancelModification) {
break;
}
}
_cancelModificationがYESに設定されている場合、forループは壊れており、問題ありません。NSLog行をコメントアウトすると、YESに変更されたときに_cancelModificationは無視されます。