J'écris un programme d'utilisateur final de Cocaa OS X (Leopard 10.5+) utilisant des horodatages pour calculer les statistiques pendant combien de temps quelque chose est affiché à l'écran. Le temps est calculé périodiquement tandis que le programme fonctionne à l'aide d'un NSTIMER répété. Un problème se produit si un utilisateur final ou NTP modifie l'horloge système. Je pense que j'ai besoin d'un point de référence non changeant à temps afin que je puisse calculer le nombre de secondes passées depuis lors. Par exemple, disponibilité du système. 10.6 a J'ai essayé de créer un compteur de temps à l'aide de NSTIMER, mais ce n'est pas précis. Nstimer a plusieurs modes de course différents et ne peut en exécuter qu'un à la fois. NSTIMER (par défaut) est mis dans le mode Exécuter défaut em>. Si un utilisateur commence à manipuler l'interface utilisateur pendant une période suffisamment longue, cela entrera nsventtrackingrunloopmode em> et saute sur le mode Exécution em> par défaut em>, ce qui peut conduire à des tirages NSTimer étant ignorés, ce qui le fait une manière inexacte de compter des secondes. p>
J'ai également pensé à créer un thread séparé (Nsrunloop) pour exécuter un second compteur NSTIMER, ce qui en empêche les interactions de l'interface utilisateur. Mais je suis très nouveau à la multi-filetage et j'aimerais rester à l'écart de cela si possible. En outre, je ne suis pas sûr que cela fonctionnerait avec précision si la CPU ne devait pas indiquer une autre application (Photoshop rendant une image vaste, etc ...), provoquant que ma Nsrunloop soit mise en attente pour gâcher son NSTIMER. P>
J'apprécie toute aide. :) p> [NSDate Date] CODE> est utilisé pour capturer des horodatages, Démarrer Strong> et Terminer Strong>. Calcul de la différence entre les deux dates en secondes est trivial. P>
[nsdate date] code> s'appuie sur l'horloge système, donc si elle est modifiée, la variable
- (NSTimeInterve) SystemupTime code>, une partie de
nsprocessinfo code>, qui fournit des heures de disponibilité système. Cependant, cela ne fonctionnera pas car mon application doit fonctionner dans 10.5. P>
3 Réponses :
D'accord, c'est un coup long, mais vous pouvez essayer de mettre en œuvre quelque chose comme Alors, supporte-moi ici, car c'est une idée étrange et est définitivement non dératristique. Mais que se passe-t-il si vous avez eu un thread de chien de garde courir pendant la durée de votre programme? Ce fil aurait, toutes les n secondes, lisez le temps système et stockez-le. Par souci d'argument, faites-en juste 5 secondes. Donc, toutes les 5 secondes, cela compare la lecture précédente à l'heure actuelle du système. S'il y a une différence "assez grosse" ("assez grosse" aurait besoin d'être définitivement supérieure à 5, mais pas trop grande em> plus grande, pour rendre compte du non-déterminisme de la programmation de processus et de la priorisation de thread), Publier une notification qu'il y a eu un changement de temps significatif. Vous auriez besoin de jouer avec le fuzzing la valeur qui constitue «assez gros» (ou suffisamment petite, si l'horloge a été réinitialisée à une heure antérieure) pour vos besoins de précision. P>
Je sais que c'est une sorte de hacky, mais sauf une autre solution, que pensez-vous? Pourrait-il, ou quelque chose comme ça, résoudre votre problème? P>
D'accord, vous avez donc modifié votre question initiale pour dire que vous préféreriez ne pas utiliser de fil de garde, car vous êtes nouveau à multithreading. Je comprends la peur de faire quelque chose d'un peu plus avancé que ce que vous êtes à l'aise, mais cela pourrait finir par être la seule solution. Dans ce cas, vous pourriez avoir un peu de lecture à faire. =) p>
Et oui, je sais que quelque chose comme de Photoshop peigne la merde hors du processeur est un problème. Une autre solution (encore plus compliquée) serait de, au lieu d'avoir un watchDog thread em>, avoir un chien de garde distinct processus em> qui a une priorité absolue afin qu'il soit un peu plus immunisé pour le processeur peigne. Mais encore une fois, cela devient vraiment compliqué. P>
Je vais laisser toutes mes autres idées ci-dessus pour l'amour de l'exhaustivité, mais il semble que l'utilisation de la disponibilité du système sera également un moyen valide de gérer cela. Étant donné que Nssystemclockdidchangenotification code> disponible dans Snow Leopard. P>
[[NSProcessinfo processInfo] SystemupTime] code> ne fonctionne que dans 10.6+, vous pouvez simplement appeler
mach_absolute_time () code>. Pour avoir accès à cette fonction, juste
#include
nsprocessinfo code>. P>
J'aime vraiment l'idée, mais malheureusement, je dois avoir une compatibilité léopard (10.5). On dirait que Apple mettait tout ce qui est utile en 10.6. ;)
Cette solution serait 10,5 compatible. Vous seriez essentiellement en train de mettre en œuvre votre propre version de NSSYSTEMCLOCKDIDChangenotification code>, sans utiliser une version fournie par Apple.
Ah, je n'ai pas lu le tout. J'ai vu Nssystemclockdidchangenotification et pensé "10,6 seulement :(". Ça va m'apprendre.) Oui, semblable à l'idée que j'ai ajoutée à mon édition, mais j'aimerais que quelque chose de plus simple. Je pense que tout cela ne devrait pas avoir besoin d'être nécessaire pour quelque chose de si trivial. Sur Linux, vous pouvez simplement lire Proc et saisir la disponibilité à partir de là, de bas niveau. OS X doit avoir une façon de le faire.
Que diriez-vous de [[NSProcessInfo processInfo] SystemupTime] code>? Ou fait-il également des problèmes si l'horloge est modifiée?
Non 10.5 Compatible, malheureusement. Cela fonctionne parfaitement en 10.6, même si l'horloge est modifiée à mi-chemin. Quelle que soit la variable qui lisait du processeur est ce dont j'ai besoin. BTW, j'apprécie vraiment votre aide Marc. Je vérifiais votre profil et j'ai eu quelques amis qui sont allés à rit. Campus très venteux j'entends. :)
Un dernier essai: mach_absolute_time () code>. Cela semble renvoyer la même chose.
#include
Selon ce qui conduit ce code, vous avez 2 choix: p>
mach_absolute_time () code >
. Il donnera l'intervalle de temps entre les points à laquelle vous avez appelé la fonction. Li>
[[NSAPRAC CORECENTEFENT] horodatage] code> li>
ul>
J'ai trouvé un moyen de le faire en utilisant la fonction Je n'ai pas pu obtenir Merci pour toute votre aide Marc et Mike! Vous m'avez certainement envoyé dans la bonne direction menant à la réponse. :) p>
Mach_absolute_time () CODE> Pour fonctionner correctement, probablement en raison de mon manque de connaissances, et de ne pas pouvoir trouver beaucoup de documentation sur le Web à ce sujet. Il semble saisir la même heure que
uptime () code>, mais la convertir en un double à gauche me balade. P>
[[NSAPRAC CURCELCEL] horodatage] code> a fonctionné, mais uniquement si l'application recevait des nsevents. Si l'application est allé au premier plan, il ne recevrait pas d'événements, et
[[[[NsApp CurrocleVent] horodatage] code> continuerait simplement de retourner le même horodatage et de nouveau dans une méthode de tir Nstimer, jusqu'à ce que L'utilisateur final a décidé d'interagir avec l'application à nouveau. P>
10.6 a également
Nssystemclockdidchangenotification code> qui serait certainement pratique ici.