Цель-C, отменить очередь отправки с помощью события пользовательского интерфейса.

Сценарий:

  • Пользователь нажимает кнопку с запросом на какое-либо изменение в адресной книге.
  • Вызывается метод для запуска этой модификации, и отображается окно предупреждения.
  • Чтобы отобразить окно предупреждений и поддерживать отзывчивость пользовательского интерфейса, я использовала 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!

15
задан Abdalrahman Shatou 8 April 2012 в 23:41
поделиться