9
votes

EnQUEUE Un sélecteur à la boucle de course - est [NsObject SpectsSelector: withObject: AfterDelay:] La voie à suivre?

J'aimerais avoir une méthode d'exécution une fois la méthode actuelle passée et que l'interface utilisateur a été mise à jour. Pour cette fin, j'utilise [objet performelector: @Selector (someselector) withObject: AfterDelay de ToOObject: 0.0] en ce moment. Selon La documentation d'Apple , cela crée Un NSTIMER qui déclenchera ensuite et appendez le sélecteur à la NsRunloop actuelle. Mais je ne considère pas cela très élégant. Existe-t-il un moyen simple d'enroquer directement le sélecteur à la boucle de course en cours, sans que le cacao crée une minuterie, etc.?

serait EFFACSELLORONMAINTHREADAD: withObject: WattObject: (si je suis sur le fil principal) ou Performselector: ONTHEAD: withObject: watObject: avec avec WaitonTleTone: Non faire ce que je veux avec moins de frais généraux?

acclamations et merci d'avance

mrmage


0 commentaires

4 Réponses :


6
votes

Cocoa est axé sur les événements. Vous n'avez pas "en faisant un sélecteur dans la boucle d'exécution en cours". Pour la mettre de manière simpliste: un événement envoyé à l'application (entrée de l'utilisateur, une minuterie, une activité de réseau ...) provoque l'exécution de la boucle d'exécution, ce qui entraîne des choses dans cette course de la boucle. Il y a bien sûr des "détails", mais c'est le comportement le plus fondamental.

Si vous souhaitez éteindre un sélecteur à la fin de la boucle d'exécution en cours, appelez-la en dernier ou demandez-la d'être exécutée sur une course à venir (très proche) de la boucle. Leformselector: ... Les méthodes sont la bonne façon de le faire. Ils créent une minuterie qui entraîne un événement qui entraîne des choses.

Pour plus d'informations, reportez-vous au événement de cacao -Le guide .


3 commentaires

La documentation que j'ai citée des lectures effectue le sélecteur spécifié sur le thread de courant pendant le cycle de boucle d'exécution suivant et après une période de retard optionnelle. ' Cela ne signifie-t-il pas que le sélecteur doit en quelque sorte être mis en conclusion du cycle de boucle suivant?


Bien sûr. :-) c'est via un événement tiré de la minuterie.


Accepté celui-ci parce que cela m'a donné le plus de perspectives sur ce qui se passe vraiment.



4
votes

Je ne vois rien d'inélégant à propos de la formidable: withObject: AfterDelay: méthode que vous soulignez. Cette méthode implique simplement une tâche à effectuer après l'achèvement du cycle de courant de la boucle d'exécution. De Documentation dans la section que vous avez liée à :

Effectue le sélecteur spécifié sur le fil actuel pendant la prochaine course cycle de boucle et après un délai facultatif période. Parce qu'il attend jusqu'à ce que le prochain cycle de boucle d'exécution pour effectuer la Sélecteur, ces méthodes fournissent un Délai automatique du mini de la actuellement exécutant du code. Plusieurs Les sélecteurs en file d'attente sont effectués une après l'autre dans l'ordre où ils étaient mise en file d'attente.

Un objet NSTIMER n'est pas créé pour le gérer, le sélecteur est simplement en cours d'être exécuté après un certain délai (un petit moyen de retard immédiatement après l'achèvement du cycle de boucle d'exécution). Pour que les actions que vous souhaitez accéder après des mises à jour de l'interface utilisateur ont lieu, c'est la technique la plus simple.

Pour une file d'attente plus explicite et filetée, vous pouvez regarder Nsoperations et NsoperationQuues < / a>. Un nsopérationQueue avec un maxConcurrentOverationCompte de 1 peut exécuter des opérations dans l'ordre, l'une après l'autre.


3 commentaires

Il crée une minuterie: développeur.apple.com/mac/library/documentation/cocoa/referenc e / ... : Cette méthode définit une minuterie à Effectuez le message d'asélectionner sur la boucle d'exécution du fil actuel. La minuterie est configurée pour fonctionner en mode par défaut (NsdefaultrunloopMode). Lorsque la minuterie incendie, le fil tente de déroger le message de la boucle d'exécution et de réaliser le sélecteur.


Vous êtes tous deux à la fois de droite. -PerformSelector: withObject: AfterDelay: utilise l'API de la minuterie de base de base, pas une instance NSTIMER.


Je voulais juste ajouter que la similaire à la recherche [SelfsSelector: <# (SEL) #> withObject: <# (id) #>] n'attend que la prochaine exécution de la boucle de course mais appelle la méthode immédiatement. C'est évident mais je le pose toujours là-bas.



2
votes

J'ai utilisé cette technique plusieurs fois moi-même, et je ne pense pas que ce soit cet inélégant ... Cependant, une alternative que vous pourriez essayer est la suivante:

performselectoronmainthread: withObject: WaiTrateTone: Non .

Juste parce que vous êtes déjà sur le fil principal, cela ne signifie pas que cela ne fonctionnerait pas (en fait le comportement de référence de documents qui se produira lorsqu'il sera appelé depuis le fil principal) ... et je pense que cela aurait le même comportement quand Le serviteur est défini sur Non, où il fait la queue de la demande d'exécution du sélecteur et qu'il doit être exécuté lorsque la boucle d'exécution actuelle se termine.


1 commentaires

Hmm, mes excuses - je suppose que j'ai raté cela à la fin. C'est une meilleure façon de faire ce que vous voulez faire.



4
votes

Je préfère la méthode NsRunloop "PerformSelector: Target: Argument: Ordre: Modes:". Il est garanti de ne pas exécuter le sélecteur jusqu'à la prochaine itération de la boucle d'exécution et vous n'avez pas à vous désordre avec la spécification des retards arbitraires, etc.


0 commentaires