2009-07-25 8 views
0

J'ai un petit problème ici, je laisse l'utilisateur télécharger une vidéo sur le serveur mais j'ai quelques difficultés à gérer une vue que j'utilise pour illustrer ses progrès , je sais pourquoi le problème se passe et je l'ai trouvé un moyen de contourner (sorte de) ici mon problèmeGérer une vue pendant qu'un autre processus fonctionne sur l'iPhone

donc, si l'on essaie de faire un code qui ressemble à ceci (dans un UIViewController

-(void)uploadMovie 
{ 
    UIActivityView indicator=new... 
    [self.view addSubview:indicator] 
    [uploader UploadMyMovie:data] 

} 

Ce code ne fonctionnera pas, le téléchargeur verrouillera le contrôleur et ne laissera pas le temps pour que l'indicateur arrive à l'écran à temps, j'ai trouvé attendre quelques secondes avant re appelant l'uploader fonctionne mais j'ai pris une autre approche. L'approche consistait à lancer un nouveau thread pour l'uploader et à avoir un protocole dans lequel l'objet uploader informe le UIViewController (ou un délégué) quand il commence le téléchargement, sa progression, et quand il a fini le téléchargement. Quelque chose comme

 -(void)uploadMovie 
    { 
     UIActivityView indicator=new... 
     [self.view addSubview:indicator] 
     NSThread *thread=... 
     [thread start] 
    } 

les méthodes de délégués ressemblent à ce

#pragma mark UploadProgressDelegate 

-(void)didStartUploading 
{ 

    progressLabel= [[UILabel alloc] initWithFrame:CGRectMake(93, 240, 116, 32)]; 
    ind= [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; 
    ind.center=self.view.center; 
    [progressLabel setTextColor:[UIColor blackColor]]; 
    [progressLabel setText:@"TEST"]; 
    [self.view addSubview:progressLabel]; 
    [self.view addSubview:ind]; 
    [ind startAnimating]; 
    [self.view bringSubviewToFront:progressLabel]; 
    [ind setHidesWhenStopped:TRUE]; 
    [self.view setUserInteractionEnabled:FALSE]; 
} 
-(void)progressUpdate:(NSString*)progress 
{ 
    [progressLabel setText:progress]; 
} 
-(void)didEndUploading; 
{ 
    [progressLabel removeFromSuperview]; 
    [ind stopAnimating]; 
    [ind removeFromSuperview]; 
    [progressLabel release]; 
    [ind release]; 
    [self.view setUserInteractionEnabled:TRUE]; 
} 

Cela fonctionne très bien et l'indicateur montre et tout, alors je décide de laisser l'utilisateur voir les progrès en ajoutant un UILabel (pris en compte dans le code ci-dessus), cependant pour cela la solution ne fonctionne pas, l'étiquette ne s'affiche pas et bien sûr pas de mises à jour ...

Je me demandais si quelqu'un a rencontré cette situation et a trouvé une solution pour cela? ou si vous pouvez le voir dans le code ci-dessus pourquoi l'étiquette isnt montrant ...

Merci

Répondre

1

UIKit n'est pas adapté aux threads. Si vous mettez à jour un élément d'interface utilisateur, vous devez effectuer une synchronisation dans le thread principal ou tous les paris sont désactivés.

+0

dire par la synchronisation au fil principal – Daniel

+0

Soyez dans le fil principal. Si vous créez des objets w/UI en dehors du thread principal, vos résultats seront incohérents. Ce n'est tout simplement pas thread-safe. –

+0

Ah, c'est vrai ... ça l'a fait, merci! – Daniel

1

dans certains cas, j'ai trouvé que je dois revenir au fil conducteur de faire certaines choses. ..

donc dans vos méthodes de délégués que vous feriez

[self performSelectorOnMainThread: @selector(updateLabel:) withObject:newLabelText waitUntilDone:NO]; 

puis

- (void) updateLabel:(NSString *)newLabelText 
{ 
    [progressLabel setText:newLabelText]; 
} 

Je ne suis pas sûr de savoir quelles sont les règles pour ce que les choses doivent être faites sur le fil principal plutôt que dans le fond, cependant.

+0

Pourquoi quelqu'un a-t-il marqué ce type, il ne savait pas du contexte où je devais passer cet appel, mais j'ai dû faire cet appel, merci pour l'aide – Daniel

+0

merci pour votre soutien :-) –

Questions connexes