Сценарий:
- Пользователь нажимает кнопку с просьбой о какой-либо модификации в адресной книге.
- Вызывается метод для запуска этой модификации и отображается вид предупреждения.
-
Чтобы показать представление предупреждения и сохранить отзывчивость пользовательского интерфейса, я использовал 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, чтобы остановить процесс и вернуть адресную книгу.
Проблема в том, что вы не можете этого сделать! вы не можете получить доступ к блоку и изменить любую переменную внутри него, поскольку все переменные копируются только один раз. Любое изменение переменных внутри блока во время выполнения не будет видно блоку.
Подводя итог: как остановить текущую операцию с помощью события пользовательского интерфейса?
Update:
Код процесса:
- (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;
}
Код для оповещения (мой собственный 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, _cancelModification пренебрегают, когда она изменится на YES!