2010-05-10 12 views
1

Tenir compte une classe avec ces méthodes:Comment puis-je mettre le thread principal en veille en attendant l'appel d'un délégué?

- (id) initWithFrame: (CGRect) frame 
{ 
    if (!(self = [super init])) 
     return nil; 
    webView = [[UIWebView alloc] initWithFrame:frame]; 
    [webView setDelegate:self]; 
    lock = [[NSConditionLock alloc] initWithCondition:LOCK_WAIT]; 
    return self; 
} 

- (void) setHTML: (NSString *) html 
{ 
    [lock lockWhenCondition:LOCK_WAIT]; 
    [webView loadHTMLString:html baseURL:nil]; 
    [lock unlock]; 
} 

- (void)webViewDidFinishLoad:(UIWebView *)aWebView 
{ 
    [lock lockWhenCondition:LOCK_WAIT]; 
    // Locking to be able to unlock and change the condition. 
    [lock unlockWithCondition:LOCK_GO]; 
} 

- (NSString *) stringByEvaluatingJavaScriptFromString: (NSString *) jsCommand 
{ 
    [lock lockWhenCondition:LOCK_GO]; 
    NSString * res = [webView stringByEvaluatingJavaScriptFromString:jsCommand]; 
    [lock unlock]; 
    return res; 
} 

Appelons cette classe SynchronousUIWebView. Du fil conducteur j'Execute:

webView = [[SynchronousUIWebView alloc] initWithFrame:frame]; 
[webView setHTML:html]; 
[webView stringByEvaluatingJavaScriptFromString:jsCommand]; 

Le problème semble être que le délégué n'est pas appelé jusqu'à ce que je quitte la pile d'appel en cours, que je ne le fais pas parce que je suis en attente de l'appel délégué arrive , aka impasse. Pour moi, il semble que l'appel de délégué est poussé vers une file d'attente appelée lorsque l'appel en cours est terminé. Donc la question est: puis-je modifier ce comportement?

Remarque: La raison pour laquelle cela est nécessaire est que je ne peux pas exécuter le JavaScript tant que le code HTML n'est pas chargé.

Répondre

1

Vous ne pouvez pas utiliser un UIWebView à partir d'un autre thread principal. Vous pouvez donc omettre tous vos verrous et laisser la vue Web et la boucle d'exécution gérer votre appel de délégué. Les méthodes déléguées doivent ensuite être appelées depuis le thread principal.

Le problème main-thread-only existe sur deux classes Cocoa, y compris UIKit. Cela signifie que toutes les implémentations de ces classes reposent sur l'appel du thread principal uniquement (par exemple, elles utilisent implicitement la boucle d'exécution du thread principal). Il n'est tout simplement pas possible de les utiliser sur d'autres threads, même lors de l'implémentation de votre propre verrouillage.