Attente de la terminaison d'un thread

Marroucha

Membre enregistré
30 Juin 2011
7
0
35
Bonjour à tous,
Je suis en train de parser un fichier xml, et comme l'éxécussion dure un certain moment, j'ai décidé d'utiliser les threads
Je lanse un thread dans la méthode viewDidLoad du rootViewController de cette maniére
Bloc de code:
[NSThread detachNewThreadSelector:@selector(startParsing) toTarget:self withObject:nil ];      alert = [[[UIAlertView alloc] initWithTitle:@"Parsing Elements\nPlease Wait..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles: nil] autorelease];
    [alert show];

et j'utilise un UIActivityIndicatorView * pour affirmer l'utilisateur que le fichier est en train d'étre parsé
Bloc de code:
UIActivityIndicatorView  *indicator = [[UIActivityIndicatorView alloc]       initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

     
     

    indicator.center = CGPointMake(alert.bounds.size.width / 2, alert.bounds.size.height - 50);
    [indicator startAnimating];
   [alert addSubview:indicator];
    [indicator release];






Mon probléme est que je veux forcer l'attente du terminaison de ce thread pour continuer le reste de l'application
En fait mon thread parse un document xml et charge ses éléments dans un NSMutableArray et lesinsére ensuite dans une bd SQLite
Bloc de code:
-(void) startParsing{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];    XMLToObjectParser *myParser = [[XMLToObjectParser alloc] parseXMLAtURL:url toObject:@"aliment" parseError:nil];
arrayCount = [[myParser items] count]; 
    for(int i = 0; i<=arrayCount-1 ; i++) {

         

        aliment *new = [[aliment alloc] init];
        new = (aliment *)[[myParser items] objectAtIndex:i];
        [tableau addObject:new];
        NSLog(@"élément ajouté");
    }    
    NSLog(@"Dans le thread '%d'",[tableau count]);

 
    for(int i = 0; i<[tableau count] ; i++) {

         
        aliment *new = [[aliment alloc] init];
        new = (aliment *)[tableau objectAtIndex:i];

         
        [sqlManager insertIntoDatabase:new:db];
        NSLog(@"C'est inséré");

         

        [new release];
    }
    [self performSelectorOnMainThread:@selector(dismissingAlertView) withObject:nil waitUntilDone:YES];  
    [pool release];  
}






puis le processus appelant qui est RootViewController se charge d'afficher les cellules du UITableView à partir du tableau qui a été déjà remplit par le thread avec le méthode
Bloc de code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

     

    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
       cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
   NSString *ligneTableau = [NSString stringWithFormat:@"%@ %@", [[tableau objectAtIndex:indexPath.row] type],[[tableau objectAtIndex:indexPath.row] name]];
    cell.text=ligneTableau;    // Configure the cell.
    return cell;
}


Y'a t'il une personne qui peut m'aider dans ce context et Merci beacoup
 
Je connais les threads dans d'autres langages et ce que tu dois faire dans ceux-ci, c'est de "re-lier" le thread au processus en cours.

A ce moment la, le process s'interrompt jusqu'à ce que le thread soit terminé et seulement alors le processus reprend son cours.

---------- Nouveau message ajouté à 18h08 ---------- Le message précédent a été envoyé à 18h00 ----------

En C#, la commande est myThread.Join();
 
Le thread s'achève au moment où tu ressors de ta fonction "threadée" (startParsing).
Donc il suffit de passer en paramètre de ton detach l'objet à l'origine de la création du thread (paramètre withObject qui est l'argument du selector). Après le lancement du thread, tu mets un "verrou" dans la fonction d'origine et au moment de finir ton thread il suffit d'envoyer un message à l'objet d'origine pour le "déverrouiller". Si ça peut aider, tout les threads peuvent avoir accès à mainThread.
 
Salut

Premièrement, tu déclares une variable d'instance booléenne dans la classe dans laquelle s'exécute ton mainThread (application), par exemple _threadHasFinished.
Secondement, avant le lancement du thread, tu initialises cette variable d'instance à NO. Troisièmement, tu lances ton thread. Dans la boucle principale de ton thread, à la fin de son traitement, il initialise_threadHasFinished à YES, juste avant la libération du pool de libération automatique [pool release].
Dans ton code, et plus précisément dans celui qui est exécuté au niveau de ton application (mainThread), tu places une boucle de la façon suivante:

while (! _threadHasFinished)
{
[NSThread sleepForTimeInterval:0.5]; // soit 0.5 seconde
}
suite de ton code

Cette construction n'est valable que si il n'y a aucune concurrence d'accès à une mémoire partagée. Sinon, il faut utiliser des vérous (NSLock). C'est plus compliqué car il faut veiller à ne pas provoquer des interblocages (DeadLock).

Un autre solution, consiste à utiliser les notifications, à la fin du thread tu poste une notification dont l'observateur sera le main thread. Dans cette méthode tu écris le code de la suite de l'application.
Il peut y avoir plusieurs autres solutions.

A+