Des Alternatives à dispatch_get_current_queue() pour la réalisation des blocs dans iOS 6?
J'ai une méthode qui accepte un bloc et l'achèvement du bloc. Le premier bloc doit s'exécuter en arrière-plan, tandis que l'accomplissement de bloc devrait fonctionner quelle que soit la file d'attente de la méthode a été appelée.
Pour ce dernier, j'ai toujours utilisé dispatch_get_current_queue()
, mais il semble que c'est déconseillé dans iOS 6 ou supérieur. Que dois-je utiliser à la place?
- pourquoi dites-vous
dispatch_get_current_queue()
est obsolète dans iOS 6? les docs ne rien dire à ce sujet - Le compilateur se plaint-il. Essayez-la.
- Vérifiez le fichier d'en-tête, il déclare qu'il est depricated
- Outre les discussions sur ce qui est le meilleur de la pratique, je vois [NSOperationQueue currentQueue] qui peut répondre à la question. Pas sûr au sujet de réserves quant à son utilisation.
- trouvé avertissement ------ [NSOperationQueue currentQueue] pas le même que dispatch_get_current_queue() ----- Il parfois renvoie null ---- dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"q(0,0) est:%@", dispatch_get_current_queue()); NSLog(@"cq(0,0) est:%@", [NSOperationQueue currentQueue]); }); ----- q(0,0) est <OS_dispatch_queue_root: com.apple.de la racine.par défaut-qos[0x100195140]> cq(0,0) est (null)----- depricated ou pas dispatch_get_current_queue() semble être la seule solution que je vois pour les rapports actuels de la file d'attente dans toutes les conditions
Vous devez vous connecter pour publier un commentaire.
Sur le modèle de "l'exécuter sur n'importe quel file d'attente de l'appelant était" est séduisante, mais finalement pas une bonne idée. Cette file d'attente pourrait être une priorité de la file d'attente, la file d'attente principale, ou une autre file d'attente avec de curieuses propriétés.
Mon approche préférée pour ce est-à-dire "la fin du bloc s'exécute sur une mise en œuvre définies file d'attente avec les propriétés suivantes: x, y, z", et de laisser le bloc d'envoi à une file d'attente particulière si l'appelant veut plus de contrôle que cela. Typique d'un ensemble de propriétés pour spécifier serait quelque chose comme "série, non réentrant, et asynchrone par rapport à tout autre visible par l'application de la file d'attente".
** EDIT **
Catfish_Man mis un exemple dans les commentaires ci-dessous, je suis juste de l'ajouter à sa réponse.
C'est fondamentalement pas la bonne approche pour l'API, vous êtes en décrivant à prendre. Si une API accepte un bloc et l'achèvement de bloc à exécuter, les faits suivants doivent être remplies:
Le "bloc à exécuter" doit être exécuté sur une file d'attente interne, par exemple une file d'attente qui est privé de l'API et donc entièrement sous l'API de contrôle. La seule exception à cette règle est si l'API spécifiquement déclare que le bloc sera exécuté sur la file d'attente principale ou l'une des mondiale simultanée des files d'attente.
La fin du bloc de toujours être exprimé comme un n-uplet (file d'attente, bloc), à moins que les mêmes hypothèses que pour le #1 vrai, par exemple l'achèvement du bloc sera exécuté sur une connues dans le monde de la file d'attente. L'achèvement de bloc doit en outre être distribué asynchrone sur le passé-dans la file d'attente.
Ce ne sont pas seulement stylistique points, ils sont tout à fait nécessaire si votre API est d'être à l'abri de blocages ou de l'autre bord de cas d'un comportement qui, autrement, accrochez vous à partir de l'arbre le plus proche, un jour. 🙂
Autres réponses sont grands, mais pour moi la réponse est d'ordre structurel. J'ai une méthode comme ceci sur un Singleton:
qui a deux dépendances, qui sont:
et
De cette façon je peux centraliser mes appels à l'expédition sur l'autre fil.
Vous devez être prudent au sujet de votre utilisation de
dispatch_get_current_queue
en premier lieu. À partir du fichier d'en-tête:Que vous pourriez faire une de deux choses:
De conserver une référence à la file d'attente vous avez posté sur (si vous l'avez créé via
dispatch_queue_create
), et de l'utiliser qu'à partir de là.Utilisation définies par le système de files d'attente via
dispatch_get_global_queue
, et de garder une trace de celui que vous utilisez.Efficacement, alors compter sur le système pour garder une trace de la file d'attente, vous êtes sur, vous allez avoir à le faire vous-même.
dispatch_get_current_queue()
pour savoir qui de la file d'attente? Parfois, le code qui a besoin de savoir qui de la file d'attente, il est exécuté sur n'a pas de contrôle ou de connaissances. J'ai beaucoup de code qui peut (et doit) être exécuté sur un arrière-plan de la file d'attente, mais de temps en temps besoin de mettre à jour l'interface graphique (barre de progression, etc), et doit donc dispatch_sync() sur la file d'attente principale pour ces opérations. Si déjà dans la file d'attente principale, dispatch_sync() de verrouillage, pour toujours. Ça va me prendre des mois pour refactoriser mon code pour cela.Pour ceux qui doivent encore dans la file d'attente de comparaison, vous pourrez comparer les files d'attente de par leur étiquette ou précise.
Cochez cette https://stackoverflow.com/a/23220741/1531141
Apple avait déconseillé
dispatch_get_current_queue()
, mais a laissé un trou dans un autre endroit, nous avons donc encore en mesure d'obtenir en cours d'expédition de la file d'attente:Cela fonctionne pour la file d'attente principale, au moins.
Notez que
underlyingQueue
propriété est disponible depuis iOS 8.Si vous avez besoin pour effectuer la fin du bloc dans l'original de la file d'attente, vous pouvez également utiliser
OperationQueue
directement, je veux dire sans PGCD.C'est un moi trop de réponse. Je vais donc parler de notre cas d'utilisation.
Nous avons une couche de services et la couche d'INTERFACE utilisateur (parmi d'autres couches). La couche de services exécute des tâches en arrière-plan. (Tâches de manipulation de données, CoreData tâches, appels Réseau, etc). La couche de service a un couple de fonctionnement des files d'attente à satisfaire les besoins de la couche d'INTERFACE utilisateur.
La couche d'INTERFACE utilisateur repose sur la couche de services pour faire son travail et puis exécutez le succès de l'achèvement du bloc. Ce bloc peut avoir UIKit du code. Un cas d'utilisation simple pour obtenir tous les messages sur le serveur et de le recharger l'affichage de la collection.
Ici, nous garantissons que les blocs qui sont transmis à la couche de services sont envoyés sur la liste d'attente sur laquelle le service a été invoqué sur. Depuis dispatch_get_current_queue est une méthode dépréciée, nous utilisons la NSOperationQueue.currentQueue pour obtenir de l'appelant file d'attente en cours. Remarque importante sur cette propriété.
Depuis que nous avons toujours demander l'aide de nos services sur une file d'attente connu (à Notre clientèle les files d'attente et de la file d'attente Principale) cela fonctionne bien pour nous. Nous avons des cas où serviceA peut appeler serviceB qui peut appeler serviceC. Depuis que nous avons de contrôle où le premier appel de service est effectué à partir d', nous savons que le reste de la les services suivent les mêmes règles.
Donc NSOperationQueue.currentQueue retournera toujours un de nos Files d'attente ou les MainQueue.