Par contre, pour ce qui est des applis 32/64 bits, va falloir un proco 64 bits pour développer une appli 64 bits ? ou il y aura un moyen pour les faire tourner en 32 bits, vu que Leopard gère le 32 aussi bien que le 64, ça paraà®trait logique, non ?
Apple arrive bien à faire des exécutables Intel avec Xcode sur un PPC et inversement :P Je ne pense pas qu'il y ait des contraintes de processeurs pour quoi que ce soit...
Bon, je viens de finir de refaire mes 3 classes, qui seront pour l'instant la base d'une première version de ma version GUI. Je les balance ici, dans la seule intention que vous me fassiez part (si vous le voulez bien, bien entendu), de vos remarques, critiques ou commentaires qui seront les bienvenus. J'aimerai bien partir tranquillement sur ma GUI et ne pas m'apercevoir que pas mal de choses que j'ai faites avant sont bancales, pour me consacrer pleinement à Cocoa.
Merci bien !
Les 3 classes, Operation, Account et AccountOwner :
- (void) setOperationValueDate: (NSDate*) valdate {<br /> <br /> [valdate retain];<br /> [operationValueDate release];<br /> //release etant donne que ce n est plus la meme date par defaut<br /> if([operationDate retainCount] != 1){<br /> [operationDate release];<br /> }<br /> operationValueDate = valdate;<br />}
Grrr ! D'où ton setter se mêle de faire un release sur operationDate ? C'est incroyable ça ! En général, on a jamais besoin d'utiliser "retainCount" quand on code... Juste pour débuguer.
En fait, j'ai fait cette manip parce que dans le constructeur, je met là date de valeur par defaut vers la date de l'operation. Donc la date possède à ce moment là un retainCount de 2.
Ensuite si je souhaite la modifier, cette date de valeur, je retain la nouvelle, je release l'ancienne.
En fait j'ai pensé à plusieurs cas: 1 er cas, on utilise le setter juste après le constructeur, donc operationDate et operationValueDate pointent tout les deux sur le même objet, retain count de 2. Donc ce retain count doit devenir 1 si cet objet est différent de l'actuel.
Autre cas, j'avais déjà fait pointer operationValueDate sur un autre objet que celui pointé par operationDate, auquel cas ces deux dates sont retenues "normalement", d'où la présence de mon if.
En gros la release sur operationDate ne se fait que lorsque c'est le "premier" setter sur mon objet.
Je me trompe ?
Merci Shclum pour ta patience !
PS: Sous IE (désolé je suis pas chez moi là ), les quotes pour le code n'ont pas de scroll bar, d'où un bon scroll de la mort qui en découle !
En fait, j'ai fait cette manip parce que dans le constructeur, je met là date de valeur par defaut vers la date de l'operation. Donc la date possède à ce moment là un retainCount de 2.
Non, de 3 (au moins), car celui qui aura appelé le constructeur n'aura pas manqué de mettre un retain (temporaire) sur "date" ; tu en ajoutes 2...
Ensuite si je souhaite la modifier, cette date de valeur, je retain la nouvelle, je release l'ancienne.
Oui, c'est ce qu'il faut faire...
En fait j'ai pensé à plusieurs cas: 1 er cas, on utilise le setter juste après le constructeur, donc operationDate et operationValueDate pointent tout les deux sur le même objet, retain count de 2. Donc ce retain count doit devenir 1 si cet objet est différent de l'actuel.
Ben là avec ton truc il va devenir 0 :P (et crash en prévision dans le destructeur...)
Autre cas, j'avais déjà fait pointer operationValueDate sur un autre objet que celui pointé par operationDate, auquel cas ces deux dates sont retenues "normalement", d'où la présence de mon if.
En gros la release sur operationDate ne se fait que lorsque c'est le "premier" setter sur mon objet.
Je me trompe ?
Oui... Il se fait complètement aléatoirement en fonction de la "vie" de l'objet date avant le constructeur et entre les appels...
[Session started at 2007-06-28 18:25:49 +0200.] 2007-06-28 18:25:49.899 MoneyOrganizer_v0.2[2484] Valeur initiale retainCount pour Date : 3 Pour Value Date 3
2007-06-28 18:25:49.899 MoneyOrganizer_v0.2[2484] Valeur modifiee retainCount pour Date : 2 Pour Value Date 2
MoneyOrganizer_v0.2 has exited with status 0.
Ce qui est en théorie, et si je ne trompe point, normal :
j'essaie de m'auto-persuader là , donc juste après l'initialisation de l'objet Operation, le retainCount de la date est de 3, 2 retains fait dans le constructeurs, ce qui ets attendu pour mettre valueDate par defaut identique à la date de l'opération, et un retain fait lors de la saisie du string en paramètre du constructeur.
Si je ne fais rien de plus, que ma méthode se termine et d'autres sont lancées, le string en param qui est dans l'autoreleasePool va donc être libéré, et ma date aura uen valeur de retain de 2, car nécessaire encore pour operationDate et operationValueDate. Là ça va.
Imaginons que la méthode se déroule comme suit après dans l'exemple, une modification de la value Date avec un nouveau String.
Ce nouveau String à un retainCount de 1, on appelle le setter, qui fait un retain immediatement dessus, la nouvelle valueDate passe à 2, on release l'ancienne (donc si c'est le premier setter de l'objet, la date normale passe a un retain count de 1 si on considère que l'on est plus dans le bloc de l'initialisation).
Après l'exécution de cette méthode dans le même bloc que l'init, operationDate est à 2, et valueDate aussi, ce qui est conforme au résultat voulu non ? Puisque les deux objets Strings vont ensuite être release grâce à la pool ?
Est-ce alors un comportement normal et qui n'occasionne pas de perte de mémoire ?
C'est pas comme si je me posais trop de question et que ça me faisait que m'embrouiller hein !
Edit: En utilisant les NSSortDescriptors, je trie mon tableau et comme la méthode retourne un NSArray, je fais donc "naturellemen"
Comme dans l'exemple fournit dans l'API à l'exception près que dans l'exemple, ce ne sont pas les mêmes tableaux. Dans mon cas, quand je compile et j'exécute, ça marche impec, pas de soucis, mais j'ai un warning à la compilation "Assignement from distinct Objective-C type". Je comprend pourquoi puisque un NSArray est retourné, alors que mon tableau trié est un NSMutablearray, mais vu que c'est une sous classe, je comprend moins.
Ce qui est en théorie, et si je ne trompe point, normal :
j'essaie de m'auto-persuader là , donc juste après l'initialisation de l'objet Operation, le retainCount de la date est de 3, 2 retains fait dans le constructeurs, ce qui ets attendu pour mettre valueDate par defaut identique à la date de l'opération, et un retain fait lors de la saisie du string en paramètre du constructeur.
Si je ne fais rien de plus, que ma méthode se termine et d'autres sont lancées, le string en param qui est dans l'autoreleasePool va donc être libéré, et ma date aura uen valeur de retain de 2, car nécessaire encore pour operationDate et operationValueDate. Là ça va.
Oui, les deux restants seront pour un libéré par l'auto-release pool et pour l'autre libéré par ton destructeur...
Imaginons que la méthode se déroule comme suit après dans l'exemple, une modification de la value Date avec un nouveau String.
Ce nouveau String à un retainCount de 1, on appelle le setter, qui fait un retain immediatement dessus, la nouvelle valueDate passe à 2, on release l'ancienne (donc si c'est le premier setter de l'objet, la date normale passe a un retain count de 1 si on considère que l'on est plus dans le bloc de l'initialisation).
Après l'exécution de cette méthode dans le même bloc que l'init, operationDate est à 2, et valueDate aussi, ce qui est conforme au résultat voulu non ? Puisque les deux objets Strings vont ensuite être release grâce à la pool ?
Euh date ? string ? Ne confonds pas tout, j'y comprends plus rien :P Mais à priori c'est ça, sauf qu'il n'y en aura qu'un relâché par la pool et l'autre et aux soins de la classe, donc c'est le destructeur qui s'en occupera.
Est-ce alors un comportement normal et qui n'occasionne pas de perte de mémoire ?
C'est pas comme si je me posais trop de question et que ça me faisait que m'embrouiller hein !
Faut pas trop se poser de question ; chaque objet gère sa mémoire de manière symétrique ; là où il pose un retain, il envoie un release plus tard. Et s'il ne sait pas quand envoyer le release (après avoir donné l'objet retenu à un autre objet par exemple), il le met dans l'AutoReleasePool et s'en lave les mains.
Edit: En utilisant les NSSortDescriptors, je trie mon tableau et comme la méthode retourne un NSArray, je fais donc "naturellemen"
Comme dans l'exemple fournit dans l'API à l'exception près que dans l'exemple, ce ne sont pas les mêmes tableaux. Dans mon cas, quand je compile et j'exécute, ça marche impec, pas de soucis, mais j'ai un warning à la compilation "Assignement from distinct Objective-C type". Je comprend pourquoi puisque un NSArray est retourné, alors que mon tableau trié est un NSMutablearray, mais vu que c'est une sous classe, je comprend moins.
Cela fonctionne aussi et sans warning. Faut-il caster ou utiliser cette seconde solution ?
Si "operationTab" est mutable et que tu l'affectes avec le résultat d'une fonction qui renvoie du non mutable, il ne va pas être content, c'est sûr, d'où le warning...
Il faut utiliser :
- (void)sortUsingSelector:(SEL)comparator
de NSMutableArray ; ça trie directement le tableau mutable et ça évite de créer un autre objet.
Ta seconde solution me paraà®t très douteuse... Normalement ça ne change pas l'array.
pour trier le tableau, j'ai casté en MutableArray, et là , plus de warning, donc c'est réglé.
Très mauvais idée... Ne jamais caster un mutable en non mutable et inversement... Tu vas droit au mur avec des crash et des leaks en prévision.
Le compilateur est complaisant avec ce genre d'idées, puisque de toute façon, on peut caster n'importe quel objet en id et id en n'importe quel autre objet.
Elles ne te plaisent pas les méthodes de NSMutableArray pour le tri ??
Ah ben oui, celle de mutable array, mais je pensais pouvoir juste utiliser celle de array dont elle héritait, mais en fait non, merci encore une fois, y'a des jours où faut que j'ouvre les n'oe“ils !
Réponses
Par contre, pour ce qui est des applis 32/64 bits, va falloir un proco 64 bits pour développer une appli 64 bits ? ou il y aura un moyen pour les faire tourner en 32 bits, vu que Leopard gère le 32 aussi bien que le 64, ça paraà®trait logique, non ?
Je ne pense pas qu'il y ait des contraintes de processeurs pour quoi que ce soit...
Merci bien !
Les 3 classes, Operation, Account et AccountOwner :
et son implémentation
Et la dernière (si y'a des masos pour la regarder !)
Grrr ! D'où ton setter se mêle de faire un release sur operationDate ? C'est incroyable ça !
En général, on a jamais besoin d'utiliser "retainCount" quand on code... Juste pour débuguer.
Ensuite si je souhaite la modifier, cette date de valeur, je retain la nouvelle, je release l'ancienne.
En fait j'ai pensé à plusieurs cas: 1 er cas, on utilise le setter juste après le constructeur, donc operationDate et operationValueDate pointent tout les deux sur le même objet, retain count de 2. Donc ce retain count doit devenir 1 si cet objet est différent de l'actuel.
Autre cas, j'avais déjà fait pointer operationValueDate sur un autre objet que celui pointé par operationDate, auquel cas ces deux dates sont retenues "normalement", d'où la présence de mon if.
En gros la release sur operationDate ne se fait que lorsque c'est le "premier" setter sur mon objet.
Je me trompe ?
Merci Shclum pour ta patience !
PS: Sous IE (désolé je suis pas chez moi là ), les quotes pour le code n'ont pas de scroll bar, d'où un bon scroll de la mort qui en découle !
Non, de 3 (au moins), car celui qui aura appelé le constructeur n'aura pas manqué de mettre un retain (temporaire) sur "date" ; tu en ajoutes 2...
Oui, c'est ce qu'il faut faire...
Ben là avec ton truc il va devenir 0 :P (et crash en prévision dans le destructeur...)
Oui... Il se fait complètement aléatoirement en fonction de la "vie" de l'objet date avant le constructeur et entre les appels...
J'ai enlevé mon if, et laissé un setter "normal" pour cette méthode. En fait ce que j'ai fait n'était pas logique.
Maintenant lorsque j'exécute ceci :
[Session started at 2007-06-28 18:25:49 +0200.]
2007-06-28 18:25:49.899 MoneyOrganizer_v0.2[2484] Valeur initiale retainCount pour Date : 3
Pour Value Date 3
2007-06-28 18:25:49.899 MoneyOrganizer_v0.2[2484] Valeur modifiee retainCount pour Date : 2
Pour Value Date 2
MoneyOrganizer_v0.2 has exited with status 0.
Ce qui est en théorie, et si je ne trompe point, normal :
j'essaie de m'auto-persuader là , donc juste après l'initialisation de l'objet Operation, le retainCount de la date est de 3, 2 retains fait dans le constructeurs, ce qui ets attendu pour mettre valueDate par defaut identique à la date de l'opération, et un retain fait lors de la saisie du string en paramètre du constructeur.
Si je ne fais rien de plus, que ma méthode se termine et d'autres sont lancées, le string en param qui est dans l'autoreleasePool va donc être libéré, et ma date aura uen valeur de retain de 2, car nécessaire encore pour operationDate et operationValueDate. Là ça va.
Imaginons que la méthode se déroule comme suit après dans l'exemple, une modification de la value Date avec un nouveau String.
Ce nouveau String à un retainCount de 1, on appelle le setter, qui fait un retain immediatement dessus, la nouvelle valueDate passe à 2, on release l'ancienne (donc si c'est le premier setter de l'objet, la date normale passe a un retain count de 1 si on considère que l'on est plus dans le bloc de l'initialisation).
Après l'exécution de cette méthode dans le même bloc que l'init, operationDate est à 2, et valueDate aussi, ce qui est conforme au résultat voulu non ? Puisque les deux objets Strings vont ensuite être release grâce à la pool ?
Est-ce alors un comportement normal et qui n'occasionne pas de perte de mémoire ?
C'est pas comme si je me posais trop de question et que ça me faisait que m'embrouiller hein !
Edit: En utilisant les NSSortDescriptors, je trie mon tableau et comme la méthode retourne un NSArray, je fais donc "naturellemen"
Comme dans l'exemple fournit dans l'API à l'exception près que dans l'exemple, ce ne sont pas les mêmes tableaux. Dans mon cas, quand je compile et j'exécute, ça marche impec, pas de soucis, mais j'ai un warning à la compilation "Assignement from distinct Objective-C type". Je comprend pourquoi puisque un NSArray est retourné, alors que mon tableau trié est un NSMutablearray, mais vu que c'est une sous classe, je comprend moins.
De plus si j'écris juste
Cela fonctionne aussi et sans warning. Faut-il caster ou utiliser cette seconde solution ?
Oui, les deux restants seront pour un libéré par l'auto-release pool et pour l'autre libéré par ton destructeur...
Euh date ? string ? Ne confonds pas tout, j'y comprends plus rien :P Mais à priori c'est ça, sauf qu'il n'y en aura qu'un relâché par la pool et l'autre et aux soins de la classe, donc c'est le destructeur qui s'en occupera.
Faut pas trop se poser de question ; chaque objet gère sa mémoire de manière symétrique ; là où il pose un retain, il envoie un release plus tard. Et s'il ne sait pas quand envoyer le release (après avoir donné l'objet retenu à un autre objet par exemple), il le met dans l'AutoReleasePool et s'en lave les mains.
Si "operationTab" est mutable et que tu l'affectes avec le résultat d'une fonction qui renvoie du non mutable, il ne va pas être content, c'est sûr, d'où le warning...
Il faut utiliser :
de NSMutableArray ; ça trie directement le tableau mutable et ça évite de créer un autre objet.
Ta seconde solution me paraà®t très douteuse... Normalement ça ne change pas l'array.
pour trier le tableau, j'ai casté en MutableArray, et là , plus de warning, donc c'est réglé.
Je vais pouvoir commencer ma GUI et ne me consacrer alors plus qu'a mes erreurs d'outlets et autre, en sachant que je pars sur une base saine.
Sûrement à bientôt sur d'autres topics !
Très mauvais idée... Ne jamais caster un mutable en non mutable et inversement... Tu vas droit au mur avec des crash et des leaks en prévision.
Le compilateur est complaisant avec ce genre d'idées, puisque de toute façon, on peut caster n'importe quel objet en id et id en n'importe quel autre objet.
Elles ne te plaisent pas les méthodes de NSMutableArray pour le tri ??