Сценарий:
Чтобы отобразить окно предупреждений и поддерживать отзывчивость пользовательского интерфейса, я использовала dispatch_queue:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_sync(dispatch_get_main_queue(), ^{
// Показать окно предупреждений
});
});
Запустите процесс изменения адресной книги, используя:
dispatch_async(modifyingAddressBookQueue, ^{});
Теперь я хочу предоставить пользователю возможность отменить процесс в любое время (конечно, перед сохранением адресной книги). Поэтому, когда он нажимает кнопку отмены в листе предупреждений, я хочу получить доступ к блоку отправки, установить определенный BOOL, чтобы остановить процесс и вернуть адресную книгу.
Проблема в том, что вы не можете этого сделать! вы не можете получить доступ к блоку и изменить любую переменную внутри него, так как все переменные копируются только один раз. Любое изменение переменных внутри блока во время выполнения не будет замечено блоком.
Подводя итог: как остановить текущую операцию с помощью события пользовательского интерфейса?
Обновление:
Код для процесса:
- (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 (моя собственная библиотека)
- (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, _cancelModification игнорируется, когда она меняется на YES!