Objective-C, annuler une file d'attente d'expédition à l'aide d'un événement d'interface utilisateur

Scénario:

  • Utilisateur appuie sur un bouton demander un certain type de modification sur le carnet d'adresses.
  • Une méthode est appelée au démarrage de cette modification et une alerte de vue s'affiche.
  • Afin de montrer l'affichage des alertes et de garder l'INTERFACE utilisateur réactive, j'ai utilisé dispatch_queue:
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                     dispatch_sync(dispatch_get_main_queue(), ^{
                       //Show the alert view
                     });
                   });
  • Démarrer le processus de carnet d'adresses modification à l'aide de:
    dispatch_async(modifyingAddressBookQueue, ^{});

Maintenant, je veux offrir à l'utilisateur la possibilité d'annuler le processus à tout moment (bien sûr avant de sauvegarder le carnet d'adresses). Alors, quand il appuie sur le bouton annuler dans l'alerte de la feuille, je veux accéder à l'envoi de bloc, jeu de certains BOOL pour arrêter le processus et de revenir le carnet d'adresses.

Le problème est, vous ne pouvez pas faire ça! vous ne pouvez pas accéder au bloc et le changement de la variable à l'intérieur d'elle car toutes les variables sont copiés qu'une seule fois. Tout changement de variables à l'intérieur du bloc, tout en étant exécuté ne pas être vus par le bloc.

Pour résumer: Comment arrêter une opération à l'aide d'une INTERFACE utilisateur événement?

Mise à jour:

Le code pour le processus:

- (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;

}

Code pour alertview (mon propre lib) délégué

- (void) alertViewProgressCancel:(ASAlertViewProgress *)alertView { //This is a private lib.


    if (cancelledPtr)
    {
        NSLog(@"stopping");

        *cancelledPtr = YES;
    }

}

Dans l'interface, je déclare

BOOL*   cancelledPtr;

Mise à jour 2:

C'est vraiment frustrant! pour le code suivant

for (NSMutableDictionary *contactDictionary in _contactArray) {

            NSLog(@"%d", _cancelModification);
            if (_cancelModification) {
                break;
            }
}

si _cancelModification est réglé sur OUI, la boucle est cassé et c'est OK. Une fois que j'en commentaire le NSLog ligne, le _cancelModification est négligé quand il se transforme en OUI!

source d'informationauteur Abdalrahman Shatou