2010-12-02 4 views
1

tout le monde. Je veux comprendre, comment je dois gérer des situations lorsqu'une méthode asynchrone a le paramètre "didFinish: @selector (SEL)". Mon exemple de code est:Comment vaut-il mieux attendre qu'une méthode asynchrone soit terminée dans l'application iPhone?

// 
// Authentication check 
- (void)authenticationSuccess: (GDataServiceTicket*) ticket 
     authenticatedWithError: (NSError*) error { 

    if (error == nil) 
    { 
     NSLog(@"authentication success"); 
    } 
    else 
    { 
     NSLog(@"authentication error"); 
    } 
} 
// 

- (void) fetchFeedOfSpreadsheets { 

    //create and authenticate to a google spreadsheet service 
    if (!(mService)) 
    { 
     GDataServiceGoogleSpreadsheet *service = [self spreadsheetService]; 
     [mService autorelease]; 
     mService = [service retain];  
    } 

    // check autentication success (invoke "authenticationSuccess" method for debug success & error) 
    [mService authenticateWithDelegate: self 
       didAuthenticateSelector:@selector(authenticationSuccess: 
               authenticatedWithError:) ]; 


    // HERE I WANT TO MAKE A PAUSE AND WHAIT THE RESULT, EITHER I AUTHENTICATED OR NOT 
    // AND MAKE AN "IF" STATEMENT TO CONTINTUE WORKING ON SERVER, OR RETURN ERROR 


    //fetch retrieves the feed of spreadsheets entries 
    NSURL *feedURL = [ NSURL URLWithString: kGDataGoogleSpreadsheetsPrivateFullFeed ]; 
    GDataServiceTicket *ticket; 
    ticket = [mService fetchFeedWithURL: feedURL 
           delegate: self 
         didFinishSelector: @selector(spreadsheetsTicket:finishedWithFeed: 
                error:) ]; 

    // HERE I WANT TO WAIT SECOND TIME. I WANT "spreadsheetsTicket:   
    // finishedWithFeed:error:" TO PROCCEED ERROR AND PUT A FEED IN SOME NSARRAY OBJECT 
    // AND AFTER THAT I WANT TO WORK WITH THAT NSARRAY RIGHT HERE 
} 

Je est clair, que je peux pousser le code que je veux dans la fin de la section de méthode « authenticationSuccess », mais il est également clair que c'est une mauvaise façon de résoudre le problèm. Il y a un certain nombre de situations comme celle-ci, où j'appelle une méthode asynchrone avec un paramètre de sélection, et je veux trouver une solution me fournissant une écriture de code flexible.

Merci d'avance.

Répondre

2

C'est une pratique standard dans Objective-C de mettre le code à exécuter après l'authentification dans la méthode authenticationSucess:. Vous pourriez ne pas l'aimer, mais c'est la vie.

Beaucoup de gens ont eu la même plainte que vous, si sur iOS 4 et plus tard, il y a quelque chose appelé blocs qui vous permettent d'écrire le code à exécuter après l'authentification dans la méthode qui déclenche l'authentification, comme dans

[mService authenticateAndExecute:^{ 
       code to be executed when successfully authenticated ; 
      }   whenError:^{ 
       code to be executed when authentication failed; 
      } ]; 

Mais dans ce cas, vous devez modifier l'API, ce qui est possible en utilisant des catégories. Voir this blog post par Mike Ash. Il a beaucoup d'autres posts sur des blocs sur le même blog, qui sont aussi très instructifs.

+0

Merci pour la réponse, Yuji. – zkaje

+0

Mais modifier gdata-objectivec-client avec des blocs est un moyen plus difficile que de rendre cette logique bublie:/..so .. je suppose que je n'ai pas de choix, et faire des insertions de code dans "didFinish: @selector"? – zkaje

0

Si vous envisagez d'utiliser une bibliothèque qui fonctionne de manière asynchrone (et par conséquent ne bloque pas votre interface utilisateur), vous devriez avoir une bonne raison d'essayer de forcer le fonctionnement synchrone.

Vous devriez rechercher une erreur d'authentification à la fin de votre méthode authenticationSuccess:authenticatedWithError: et appeler la requête suivante à partir de là si le processus aboutit. De même, dans votre spreadsheetsTicket:finishedWithFeed:error:, recherchez une erreur et poursuivez le traitement s'il n'y en a pas. Ce pourrait être une meilleure conception de faire ce travail continu dans une méthode séparée, mais c'est à vous de décider.

Y a-t-il une raison particulière pour laquelle vous souhaitez utiliser l'API GData de manière synchrone?

Questions connexes