2009-07-17 8 views
10

Je suis relativement nouveau dans Objective-C et je n'arrive pas à comprendre comment attendre de manière non bloquante. J'ai un objet qui est peuplé de manière asynchrone et je dois attendre avant de pouvoir procéder dans une autre méthode. En ce moment j'utilise la fonction de sommeil, mais cela bloque toute l'application et myObject n'est jamais chargé.Fonction d'attente non bloquante dans Objective-C

while (!myObject) 
{ 
    sleep(1); 
} 
return myObject; 

EDIT: cet extrait de code provient d'une méthode qui peut être appelée avant le chargement de myObject. Dans ce cas, je veux réellement bloquer dans cette méthode, mais mon code bloque tout ce qui inclut myObject d'être chargé.

+0

Merci à la réponse de Chuck, je trouve cette question et mis en œuvre à l'aide de son deuxième extrait de code: http: //stackoverflow.com/questions/149646/best-way-to-make-nsrunloop-wait-for-a-flag-to-be-set –

Répondre

6

Si vous le pouvez, donnez à la classe une méthode myObjectLoaded: à appeler lorsque l'objet en question est chargé. Sinon, l'équivalent le plus idiomatique de ce que vous avez écrit ci-dessus est de créer un minuteur qui vérifie constamment myObject et qui fait quelque chose une fois qu'il l'a trouvé.

Si vous aviez vraiment besoin de le faire au milieu d'une méthode pour une raison quelconque, vous devez créer une boucle qui continue d'exécuter le cycle. C'est l'absence d'un runloop qui bloque votre application.

0

On dirait que vous recherchez le modèle d'observateur. Apple l'appelle "notification".

+0

Pas vraiment ce que je cherche. Je ne veux pas être averti, je veux que * ce * thread soit bloqué jusqu'à ce que myObject soit chargé, mais mon code bloque myObject d'être chargé du tout. –

0

C'est parce que vous arrêtez le thread principal en attente de votre objet à charger. Ne faites pas cela, car le thread principal est le thread qui pilote l'interface utilisateur et attend la saisie de l'utilisateur. Si vous bloquez le thread principal, vous bloquez l'interface utilisateur de l'application.

Si vous voulez que le thread principal de faire quelque chose lorsque l'objet est chargé, puis créer une méthode myObjectLoaded: et appeler à partir des fils de chargement:

[myObjectController performSelectorOnMainThread:@selector(myObjectLoaded:) 
            withObject:myObject 
            waitUntilDone:NO]; 

où myObjectController peut être tout objet même se myObject.

3

NSNotification devrait résoudre le problème.

http://developer.apple.com/documentation/Cocoa/Conceptual/Notifications/Introduction/introNotifications.html

Au lieu d'attendre sur le objet, ont ce registre d'objets pour les notifications provenant de votre autre objet (disons Publisher) qui renseigne les données de manière asynchrone. Une fois cet objet Publisher terminé, envoyez-lui un NSNotification, qui sera automatiquement récupéré par votre objet en attente. Cela éliminerait l'attente aussi.

7

Cette petite pêche a fonctionné pour moi (en ordre de retarder pendant 20 secondes) ....

CFRunLoopRunInMode(kCFRunLoopDefaultMode, 20.0, false); 
Questions connexes