Question pour les pro de l'objet sous obj-c
Bonjour,
Je voudrais savoir comment on peut balayer les instances d'une classe sous obj-c et pour chaque instance appliquer une méthode en fonction d'une valeur contenue dans une propriété de cette instance.
J'ai un peu répété le mot instance mais c'est pour bien qualifier mes propos.
Je vous remercie de votre aide par avance .
Alexandre.
Je voudrais savoir comment on peut balayer les instances d'une classe sous obj-c et pour chaque instance appliquer une méthode en fonction d'une valeur contenue dans une propriété de cette instance.
J'ai un peu répété le mot instance mais c'est pour bien qualifier mes propos.
Je vous remercie de votre aide par avance .
Alexandre.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
A priori, le run-time Objective-C n'a aucune raison d'enregistrer lui-même les références aux instances créées; ce serait même plutôt déconseillé, puisqu'alors, les objets ne seraient jamais détruits, retenus qu'ils seraient dans une structure de données.
Il faut donc faire tout le travail toi-même.
Si tu utilises le Garbage Collector, utiliser une structure à références __weak (telle NSHashTable) marcherait. Sinon un bête tableau C.
Je propose cette solution :
on aurait alors
Ensuite, libre à toi de parcourir tableauDeToto et d'y faire ce que tu veux...
+
Chacha
Je ne connais aucun moyen de connaà®tre les instances d'une classe!
Je crois même qu'il n'y en a pas (sauf à hacker le runtime objective-C)
Je pense que ce que veux dire Al33er c'est:
- j'ai un array contenant des instances d'une même classe
- pour chaque instance, j'appelle une méthode -[propriete] qui me renvoie une valeur
- selon la valeur, j'appelle une méthode ou une autre.
Al33er, peux-tu confirmer ou infirmer ce que je viens d'écrire ?
Oula, ferme là ça devient bien complexe !!!!
Au risque de dire une connerie, il pourrait implémenter une méthode avec un "if" tout bête, non ?
Genre si c'est une instance de "NSObjet",
il créé une classe "MonObjet" de type "NSObjet"
il ajoute la méthode "SiMaPropriete"
et au lieu de créer des instances de "NSObjet" il créer des instances de "MonObjet"
Je me trompe certainement mais je risque juste d'apprendre de mes erreurs et comprendre de mieux en mieux...
D'un côté c'est pas faux (NSNotificationCenter utilise une structure __weak avec GC).
Mais en même temps, il vaut peut-être mieux ne pas alourdir le NSNotificationCenter avec toutes les instances d'une classe pour un cas si particulier ?
Bah je pense pas; sinon y a pas de difficulté, c'est pas drôle.
On va bien voir quand il repassera !
+
Chacha
Alors, moi je peux voir deux trucs dans ce qu'il dit :
Soit, il veut envoyer un message à plusieurs objets et que ces objets se servent de leur variables d'instance pour répondre au message.
Soit, il veut envoyer un message à plusieurs objets pour leur dire de s'envoyer un message qui leur est spécifié dans l'une de leur variable d'instance...
Dans le deux cas, une methode commune à tous les objets suffie.
Après il faut savoir quels objets il veut atteindre, s'il veut atteindre un certain nombre d'objets, il utilise un NSArray... S'il veut atteindre tous les objets d'une même classe, il suffit que dans son -init designé il enregistre l'objet dans un tableau global sur lequel il enverra les messages.
Maintenant il faut savoir plus précisément ce qu'il veut.
Perso, balayer une instance en plein hivers alors qu'on pourrait passer un coup de chasse neige...
Au chargement de mon application, j'appelle deux fois une méthode qui me lance un timer sur une date passée en paramétre.
A l'appuie sur un bouton, je reprogramme les timer, pour cela je dois invalider les timer existants pour eviter qu'ils se décenche et ainsi les reprogrammer.
Je voulais donc :
Balayer les instances vivantes de la classe NSTIMER et quand ils sont valident les invalider.
Voila mon besoin.
Ne vous torturez pas l'esprit. Si la méthode n'existe pas on va faire autrement.
Peut être que la solution suivante fonctionnerait, je vais tester ce soir :
Récupérer l'instance du timer créé par la méthode et ainsi agir dessus par son nom.
Cordialement.
Alexandre.
Si tu en as un nombre indéfini, utilise un NSArray.
Pas la peine de tortiller du cul pour chier droit dans un escalier en colimaçon...
D'autant que ça serait dangereux d'envoyer un message à tous les NSTimers sans distinction, car si tu utilises un framework qui a sous le capot des NSTimers, ou d'autre code qui n'a rien à voir avec ton bout de code mais utilise des NSTimers aussi (alors qu'en plus tu les "vois" pas forcément ils peuvent être "cachés" dans le code des frameworks que tu utilises....) tu risquerais du coup de faire des boulettes...
En plus, si tu utilises un NSArray, tu peux appeler une méthode sur tous les éléments de ton NSArray, avec makeObjectsPerformSelector:@selector(invalidate) par exemple pour tous les invalider d'un coup en une ligne...
Ne pas oublier de déclarer les méthodes et de "Binder" le bouton a la fonction timerDo.
Le .h
Et voilà la version nettoyée de tout ce qui est inutile :
Mais dans cette méthode, ce code suffit.
Un invalidate quelque part ?
Un release plutôt et j'essaierais de le mettre en
-(void)dealloc
avec un nslog pour voir si le dealloc est appelé en quittant
L'invalidate fait le release lui-même, et tu ne dois faire de release que si tu fais un retain avant, ou bien un alloc+init ou un copy. Aucun de ces 3 cas ne se rencontre ici...
C'est d'ailleurs pour ça que je n'ai pas mis de release dans la correction que j'ai apportée.
Le invalidate supprime le timer du runloop dans lequel il tourne, le release ne fait qu'enlever une référence. Et en prime, le invalidate fait le release nécessaire... En fait, c'est le runloop qui fait le release quand le timer se retire de la boucle d'exécution, puisqu'il n'est pas détenu par l'objet qui la créé (puisqu'on n'utilise ni retain ni alloc+init) et bien le timer est tout simplement désalloué.
D'une part, tu n'as pas fait de "alloc" ni de "copy" donc tu n'as pas à faire de release. Règle de base de la gestion mémoire
De plus avec [tt]scheduledTimerWithTimeInterval:...[/tt], le nom indique déjà que c'est un constructeur de commodité, donc que tu n'as pas à en gérer le "release", mais en plus ça installe automatiquement le timer nouvellement créé dans la RunLoop courante (et c'est la RunLoop du coup qui possède le timer du coup et garde le grapin dessus jusqu'à ce que tu l'invalides). Par contre pour le désinstaller de sur la RunLoop, il faut bien appeler "invalidate".
Pour plus d'informations sur NSTimer, CocoaDev a une page qui aide bien à ce sujet.
(Bon je me suis fait griller par psychoh13 mais je poste quand même, na :P)
Histoire que le timer tourne pas non plus pendant toute l'execution de l'application à moins que al33er en ait besoin tout le temps
Petit gris-gris de puriste ... Ne pas utiliser le verbe binder à la place de connecter.
binder se traduirait plutôt par synchroniser, ce qui n'est pas la même chose. Il signifierait par exemple ici que lorsqu'on appelle la méthode associée timerDo , le bouton deviendrait highlighted.
J'ai mis "Binder" entre guillemet pour évoquer les Binding (liens), pour que ce soit clair. Je sais bien que les verbes anglais ne font pas leur infinitif en er, mais je vais me mettre une petite tape sur les fesses pour faire plaisir à Philippe que j'aime beaucoup du fait de ses nombreux tutoriels.
Tape pas trop fort .. ou alors met un NS_Protector ! ::)
J'ai mis en sortie de ma méthode qui créer le timer le timer lui même ce qui me permet de l'invalider quand je veux.
Voilà çà fonctionne niquel.
Alexandre.