Je suis confronté à un problème de conception de mon application. P>
Fondamentalement, les suivants sont ce que je vais faire dans mon application. P>
Une seule tâche est comme ceci: p>
Il peut y avoir un certain nombre de tâches étant exécutées simultanément. p>
Les étapes dans une seule tâche sont évidemment Les tâches ont des priorités. L'utilisateur peut démarrer une tâche avec une priorité plus élevée afin que toutes les étapes de la tâche soient essayées d'être exécutées avant toutes les autres. P>
J'espère que l'interface utilisateur peut être réactivée autant que possible. p>
Alors j'allais créer une nsthead avec la priorité la plus basse. p>
Je mettais une file d'attente prioritaire personnalisée dans ce fil. Chaque étape d'une tâche devient un événement (unité de travail). Ainsi, par exemple, l'étape 1 télécharger un Json devient un événement. Après le téléchargement, l'événement génère un autre événement pour l'étape 3 et être mis dans la file d'attente. Chaque événement a son propre ensemble de priorité. P>
commandé code> (c'est-à-dire sans étape 2 télécharger JSON, étape 3 ne peut pas continuer), mais ils peuvent également être
discret code>. Je veux dire, par exemple, l'étape 4 de Task2 peut être exécutée avant l'étape 3 de la tâche1 (si le téléchargement de Task2 est peut-être plus rapide que celui de Task1) P>
5 Réponses :
par les regards, NsoperationQueue est ce que vous avez après. Vous pouvez définir le nombre d'opérations simultanées à exécuter en même temps. Si vous utilisez plusieurs nsoperation, ils courront tous en même temps ... à moins que vous ne gérez une file d'attente par vous-même, ce qui sera le même qu'utiliser NsoperationQueue P> Li>
Priorité du fil ... Je ne sais pas ce que vous voulez dire, mais dans iOS, le dessin de l'interface utilisateur, les événements et l'interaction utilisateur sont tous exécutés sur le fil principal. Si vous exécutez des objets sur le fil d'arrière-plan, l'interface sera toujours réactive, quelle que soit la manière dont vous utilisez des opérations compliquées ou lourdes sur les processeurs p> li>
Génération et manipulation des opérations Vous devez le faire sur le fil principal, car il ne prendrai aucun temps, vous ne les exécutions pas dans un fil d'arrière-plan afin que votre fil principal ne soit pas verrouillé p > li>
Coredata, je n'ai pas beaucoup travaillé avec elle spécifiquement, mais jusqu'à présent, tous les nœuds ~ j'ai travaillé avec cela fonctionne parfaitement sur les threads de fond, il ne devrait donc pas être un problème p> li>
En ce qui concerne la conception, c'est juste un point de vue ... Quant à moi, j'aurais pu avoir une nsopération par tâche et que cela gère toutes les étapes. Peut-être écrire des rappels chaque fois qu'une étape est terminée si vous souhaitez donner des commentaires ou continuer avec un autre téléchargement ou quelque chose P> Li> ul>
Merci pour votre réponse. La raison d'avoir une étape comme une nsopération est qu'une tâche peut prendre trop de temps. Et si un utilisateur souhaite hiérarchiser une tâche, une autre tâche est en cours d'exécution, l'utilisateur ne peut pas voir ce qu'il veut être fait bientôt.
En contrepartie des cœurs CPU iPhone / iPad, devrais-je simplement utiliser une nsoperationQueue ou créer plusieurs? P> blockQuote>
Deux (CPU, réseau + E / S) ou trois (CPU, Network, E / S) Serial em> Les files d'attente doivent bien fonctionner pour la plupart des cas, pour garder l'application réactive et vos programmes en streaming par ce qu'ils sont liés à. Bien sûr, vous pouvez trouver une autre combinaison / formule fonctionne pour votre distribution de travail particulière. P>
la nsoperationqueuse ou la nsopération sera-t-elle exécutée avec la priorité de fil la plus basse? L'exécution affectera-t-elle la réponse de l'interface utilisateur (je me soucie parce que les étapes impliquent des calculs)? P> blockQuote>
pas par défaut. Voir
- [Nsoperation SettheadPriority:] Code> Si vous souhaitez réduire la priorité. P>
Puis-je générer une nsoparte d'une autre et la mettre à la file d'attente? Je ne vois pas une propriété file d'attente dans Nsoperation, comment savoir la file d'attente? P> blockQuote>
Bien sûr. Si vous utilisez l'approche série que j'ai décrite, la localisation de la bonne file d'attente est suffisamment facile - ou vous pouvez utiliser un ivar. P>
Comment puis-je coopérer NsoperationQue avec Coredata? Chaque fois que j'accède à la Coredata, devrais-je créer un nouveau contexte? Sera-ce cher? P> blockQuote>
(pas de commentaire) p>
Chaque étape d'une tâche devient une nsopération, ce design est-il correct? p> blockQuote>
Oui - Diviser vos files d'attente vers la ressource qu'il est liée à une bonne idée. P>
L'affection du calcul lorsque la multithreading ne sera pas différente, simplement parce que vous utilisez Nsthread au lieu de Nsoperation. Cependant, gardez à l'esprit que les périphériques IOS actuels utilisent des processeurs à double cœur. p>
Certaines des questions que vous n'avez sont pas très spécifiques. Vous pouvez ou non utiliser plusieurs nsoperationqueuse. Tout dépend de la façon dont vous voulez l'approcher. Si vous avez des sous-classes NSOPERATION différentes, ou différentes nsblockoperations, vous pouvez gérer l'ordre d'exécution à l'aide des priorités ou vous souhaiterez peut-être avoir différentes files d'attente pour différents types d'opérations (en particulier lorsque vous travaillez avec des files d'attente en série). Personnellement, je préfère utiliser une file d'attente de fonctionnement lorsque vous traitez avec le même type de fonctionnement et avoir une file d'attente de fonctionnement différente lorsque les opérations ne sont pas liées / fiables. Cela me donne la flexibilité pour annuler et arrêter les opérations dans une file d'attente en fonction de quelque chose qui se passe (goutte de réseau, application allant à l'arrière-plan). p>
Je n'ai jamais trouvé de bonne raison d'ajouter une opération basée sur quelque chose qui se passe lors de l'exécution d'une opération en cours. Si vous avez besoin de le faire, vous pouvez utiliser la méthode de classe de NsoperationQueue, en courseuse, qui vous donnera la file d'attente de fonctionnement dans laquelle l'opération actuelle fonctionne. P>
Si vous faites des travaux de base de données utilisant Nsoperation, je vous recommanderais de créer un contexte pour chaque opération particulière. Assurez-vous d'initialiser le contexte à l'intérieur de la méthode principale, car c'est là que vous êtes sur le thread de droite de l'exécution de fond Nsoperation. P>
Vous n'avez pas nécessairement besoin d'un objet Nsoperation pour chaque tâche. Vous pouvez télécharger les données et l'analyser à l'intérieur du NSOPERATION. Vous pouvez également télécharger des données de manière abstraite et effectuer la manipulation des données du contenu téléchargé à l'aide de la propriété Block d'achèvement de Nsoperation. Cela vous permettra d'utiliser le même objet pour obtenir les données, mais avoir une manipulation de données différente. P>
Ma recommandation serait de lire la documentation pour NSOPERATION, NSBLOCKOPERATION ET NSOPERATIONEUEE. Vérifiez votre conception actuelle pour voir comment vous pouvez adapter ces classes avec votre projet actuel. Je vous suggère fortement de faire la route de la famille Nsoperation au lieu de la famille Nsthread. p>
bonne chance. p>
Merci pour votre réponse. Mais je ne trouve pas actualisationQu. / code> méthode de nsoperation. développeur.apple.com/library/mac/#documentation/c ocoa / référence / ...
@Jacksontale C'est + [NsoperationQueue actualisée] code>
Ah merci, pensais que c'est dans Nsoperation. J'ai vérifié le doc pour NsoperationQueue.
Puis-je savoir si la création d'un nouveau contexte pour chaque opération est trop chronométrée ou consommation de ressources?
Merci @Justin, j'ai édité ma réponse avec la classe appropriée pour la méthode. Jackson, une fois que vous avez créé votre pile de données de base, NsManagedObjectContext Les objets ne sont pas très coûteux. Puisque vous ne recréez pas la pile, la performance ne sera pas un problème. Avant de faire la mise en œuvre, lisez dans la documentation pour NsmanieDObjectContext. Vous devrez fusionner le contenu modifié par le nsmanagedObjectContext sur le thread d'arrière-plan avec le nsmanagedObjectContext du fil principal afin de mettre à jour la principale nsmanieDObjectContext mis à jour avec les informations d'arrière-plan enregistrées.
merci @ j2thec. Une autre question, si je mettais toutes les opérations en lecture / écriture de Coredata dans une nsopération dédiée avec MaxConCurrentCount Ensemble sur 1, puis-je simplement utiliser un contexte?
Si vous utilisez un NSManèdeObjectContext avec un type de nsprivateQueconCurencArencyPe, vous pouvez, puisque vous allez enregistrer à l'intérieur du bloc de la file d'attente privée de NsmanieDObjectContext. J'utilise personnellement nsconfinationconcurrencycurencype et le créer à l'intérieur du fil utilisé. Je ferai bientôt des tests à l'aide de NsprivateQueconfonCurencarencyPe avec sa file d'attente privée pour voir comment elle fonctionne, mais je ne l'ai pas utilisée jusqu'à présent.
Notez que si vous n'utilisez pas NSCONFINEMENTCONCULTYPE, le contexte enregistrera l'utilisation du fil actuel. Ce qui signifie que vous devrez créer le contenu dans le fil utilisé, ce qui rend impossible de réutiliser des objets de nsopération.
Utiliser GCD - c'est un cadre bien meilleur que NS * P>
Gardez tout votre accès Coredata sur une file d'attente et Dispatch_Async à la fin de vos routines pour enregistrer votre base de données CoreData. P>
Si vous avez un compte de développeur, consultez cette vidéo de la WWDC: https: //developer.apple.com/videos/wwdc/2012/?id=712 P>
Ceci est inexact. À partir de la documentation: Remarque: Dans iOS 4 et ultérieure, les files d'attente d'exploitation utilisent Grand Central Devatch pour exécuter des opérations. Avant IOS 4, ils créent des threads distincts pour des opérations non simultanées et lancent des opérations simultanées à partir du fil actuel. Pour une discussion sur la différence entre les opérations simultanées et non simultanées et la manière dont elles sont exécutées, voir la référence de la classe NSOPERATION.
Ce n'est pas inexact, il est tout simplement plus moderne et plus puissant - Pre-iOS4 est beaucoup moins pertinent maintenant et publier des files d'attente de fonctionnement IOS4 ont été «portées» à la GCD. Par conséquent, si vous commencez à partir de zéro - vous serez mieux de comprendre le GCD que la nsopération.
Je ne suis pas sûr que c'est vrai. NsoperationQueue Code> est construit sur le GCD (au moins dans les versions plus récentes de iOS) et il vous donne des choses gratuitement qui seraient beaucoup de travail en utilisant uniquement les GCD (dépendances par exemple). En général, vous devriez utiliser le cadre de niveau le plus élevé qui fera le travail.
Vérifiez les vidéos Apple, ils recommandent d'utiliser GCD plutôt que toute autre chose.
C'est que vous ne comprenez pas: NsoperationQueue est GCD. C'est un cadre de levier plus élevé qui fait beaucoup de travail pour vous. Apple recommande GCD sur Nsthread. Nsoperationqueur est GCD.
Regardez, je comprends que - mais ce que vous n'avez pas compris, c'est que, tandis que NsoperationQueue a été construit pour utiliser le GCD maintenant - il s'agit davantage d'une amélioration de l'héritage qu'une recommandation pour l'avenir. Qui devrait-il investir quelqu'un? Dans ma société, nous utilisons exclusivement GCD sur NsoperationQueue - il est plus facile à code, encourage de bons schémas de conception et plus facile à lire - IMO. Arc Conserver les cycles sucer gros temps, mais vous seriez mordu avec NsBlockOperer de la même manière.
Pouvez-vous fournir des preuves / documentation de ce que vous appelez «Amélioration de l'héritage»? Je n'ai jamais entendu parler d'une telle chose auparavant avec Nsoperation / NsoperationQueue, alors je me demande comment cela fonctionne.
Si vous regardez la vidéo WWDC, ils décrivent un modèle de conception construit autour de la GCD avec une «file d'attente d'expédition par sous-système». C'est vraiment le moyen de faire des choses, c'est super simple, donne de grandes performances et est facile à coder. La recommandation de GCD sur autre chose, vient actuellement d'un cours à la CMU ... Découvrez itunesu.itunes.apple.com/webobjects/lzdirectory.woa/ra/... - Comprendre le GCD aide également les gens à comprendre le comportement d'autres modèles de conception de cacao qui se sont déplacés vers des blocs . Nsoperation améliore simplement la performance du code hérité pour iOS4 +.
Mais en général - "Utilisez l'abstraction la plus élevée" serait la bonne réponse. Je pense que GCD n'est que "exception" dans ce cas.
Je suis désolé, mais je voulais dire une documentation pour "l'amélioration de l'héritage" concernant les sous-classes NSOPERATION / NSOPEREREQUEREQUESE. Les vidéos Apple actuelles pour WWDC, ils recommandent toujours l'utilisation de Nsoperation
L'amélioration de l'héritage est que celle-ci est passée de Nsthread à la GCD comme mise en œuvre de Nsoperation, de sorte que tout ce qui a utilisé Nsoperation au préalable ait été automatiquement bénéficié du modèle léger de GCD. S'il vous plaît regarder la vidéo que j'ai liée à (les deux en fait ...) - Le WWDC One de Kevin Van Vechtan est vraiment bon. La CMU one est également vraiment utile. Il n'y a rien de mal à NsoperationQueue en soi, mais je crois que GCD est plus facile à comprendre et plus polyvalent. Nsoperationqueur est bien si c'est ce que vous êtes déjà utilisé - mais si vous apprenez à partir de zéro, dirigez-vous droit sur GCD.
Je n'appellerais pas changer de Nsthread au GDC une amélioration héritée. Il s'agit d'un changement complet de la mise en œuvre, laissant uniquement l'interface intacte. Le GCD étant plus facile à comprendre est discutable et dépend du point de vue de l'utilisateur. J'utilise à la fois la GCD et tout le temps, et je ne trouve pas de raison ni d'informations pour dire que le GCD est vraiment bien meilleur que la nsopation, ou pourquoi quelqu'un devrait aller directement à la GCD et non évaluer la nsopération, compte tenu du fait qu'il y ait Certaines choses que la nsopération ne serait difficile à faire sous GCD (comme des dépendances).
Juste pour ajouter à la réponse de @ Justin P>
Comment puis-je coopérer NsoperationQue avec Coredata? Chaque fois que j'accède La Coredata, devrais-je créer un nouveau contexte? Sera-ce cher? P> blockQuote>
Vous devez être vraiment prudent lorsque vous utilisez
nsoperation code> avec les données de base.
Ce que vousTOUJOURS STRUT> devez vous souvenir ici, c'est que si vous souhaitez exécuter des opérations de CoreData sur un thread séparé, vous devez créer un nouveau NSManageDObjectContext code> pour ce fil et partagez le MAIN. Coordonnateur de magasin persistant du contexte d'objet (le MOC "principal" est celui du délégué de l'application). P>
Aussi, il est
très important fort> que le nouveau contexte d'objet géré pour ce thread est créé de ce fil fort>. Donc, si vous envisagez d'utiliser des données de base avec Nsoperation code> Assurez-vous d'initialiser le nouveau MOC dans la méthode
MAIN code> de NSOperation au lieu de
init p>. P>.
ici 'SA vraiment bon article sur les données de base et le filetage p>
Merci. Si je mettais toute opération de lecture / écriture Coredata dans une nsopération dédiée avec MaxConCurrentCount Ensemble sur 1, puis-je simplement utiliser un contexte? Puis-je supposer si je fixais Nsoperationqueur comme ça, il sera toujours en cours d'exécution dans un seul fil?
Malheureusement non. NsoperationQueue gère sa propre piscine de thread et détermine comment frayer des threads en fonction de la charge de travail. Donc, en bref: non, il n'y a aucune garantie qu'il fonctionnera toujours sur le même fil
C'est beaucoup de questions. Envisagez de demander à chacun une question distincte. Seule la dernière nécessite toute information sur votre application particulière.