self. ou rien ?
neospirit
Membre
Bonjour à tous,
je débute en développement sur iPhone et j'ai une interrogation qui semblera toute bête mais quelle est la différence entre :
self.maVariable = 5;
et
maVariable = 5;
La seule différence que j'ai vue c'est que quand je débugge et que je passe le curseur de la souris sur la variable, sa valeur apparait.
Si par contre il y a une autre raison (et je suppose qu'il doit y en avoir une), je veux bien que vous m'expliquiez simplement à quoi ça sert.
Merci pour votre éclaircissement
neospirit
je débute en développement sur iPhone et j'ai une interrogation qui semblera toute bête mais quelle est la différence entre :
self.maVariable = 5;
et
maVariable = 5;
La seule différence que j'ai vue c'est que quand je débugge et que je passe le curseur de la souris sur la variable, sa valeur apparait.
Si par contre il y a une autre raison (et je suppose qu'il doit y en avoir une), je veux bien que vous m'expliquiez simplement à quoi ça sert.
Merci pour votre éclaircissement
neospirit
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
En utilisant cette formulation tu accèdes normalement à la variable.
Avec self.uneVariable tu n'accèdes pas à la variable, mais à la propriété de même nom. Fait attention à cela, un self.mavariable mal utilisé peut provoquer des fuites mémoires.
Ali-qui-ne-dort-jamais pourra t'en dire plus. Moi je vais me coucher !
Si par exemple tu as déclaré dans l'interface
alors quand tu fais self.maVariable = 5; tu déclenches
Avec unEntier égal à 5. Ce qui est bien car tu préserves l'encapsulation en n'accédant pas directement à maVariable.
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17
En fait tu fais plus que cela car en utilisant les propriétés tu génères aussi une notification au centre de notification et tous les objets intéressés par la valeur de maVariable seront avertis que sa valeur a changé ce qui peut être utile ailleurs dans le code mais surtout dans l'interface.
http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/BasicPrinciples.html#//apple_ref/doc/uid/20002170-BAJEAIEE
Donc par le simple fait d'utiliser @property tu utilises plusieurs des "Design Patterns" qui sont au coeur de Cocoa
http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW6
et tu fais de la programmation objet
Je n'ai malheureusement pas eu le temps de le finir ces derniers jours (bien que cela fait qques temps que je l'ai commencé mais je suis débordé), mais je suis en train de rédiger un tutoriel sur les @property et donc à ce sujet. Même si la partie sur la notation pointée (donc la notation "self.toto = x" qui équivaut à "[self setToto:x]) n'est pas encore rédigée, tu peux déjà lire l'ébauche ici en attendant que je le termine : il répondra déjà sans doute à quelques unes de tes interrogations
merci pour vos réponses. Je comprends (presque tout). Je vais lire le tuto de AliGator.
Dites-moi si je me trompe mais dans le cadre d'une simple utilisation d'une variable "int variable" pour afficher sa valeur dans un label par exemple, y a-t-il besoin de faire appel à "self.variable" ?
Et dans le cas où je n'utilise pas cette syntaxe, où puis-je voir la valeur de "int variable" pendant le debug dans le debugger ?
Merci encore
neospirit
Excellente idée !
Rien ne t'y oblige, mais attention un "label" est un read only text view et a pour fonction d'afficher une chaà®ne de caractères, il sera incapable d'afficher un nombre, seulement le caractère correspondant à ce nombre.
Je ne connais pas assez iOS pour te conseiller dans ces parages, je suppose qu'on y utilise aussi les NSNumberFormatters (enfin je vous le souhaite), si tu peux en glisser un sur ton label alors il sera plus facile d'afficher un nombre via les bindings.
Sinon un UIALabel a une propriété texte, tu peux donc aussi déclarer un IBOutlet UIATextField *maLabel que tu pourras appeler quand tu en auras besoin dans ton code par un message [maLabel setText:[NSString stringWithFormat:@%i,maVariable]].
Il y a peut être plus simple mais je ne suis pas qualifié pour te répondre...
Que tu utilises ou pas self.maVariable tu peux toujours regarder sa valeur dans le débugger. Si tu as gardé la présentation par défaut de Xcode c'est dans le panneau droit du panneau supérieur, la première colonne "variable" et la seconde "value" http://developer.apple.com/library/ios/#documentation/DeveloperTools/Conceptual/XcodeDebugging/100-Debugging_in_the_Debugger/debugging_in_debugger.html
Il faut juste déplier le triangle "self" et tu pourras la voir avec toutes les autres variables de ton objet référencé par "self", les bindings n'ont rien à voir ce ne sont que des méthodes pour accéder de manière KVO-KVC compliant à ces variables.
C'est ce que j'ai fait sur un UILabel, exactement : "decompteLabel.text = [NSString stringWithFormat:@allez encore %d jours avant la retraite, resultatCalcul];"
Et ça marche bien (je vous rassure, ce n'est pas le vrai texte qui sera dans mon application )
Pour le reste, j'y travaille
Merci
neospirit
après un week end intense de programmation (ma femme ne m'a pas encore quitté mais ça devrait pas tarder ), j'ai une application en presque bon état et sans crash.
J'ai cependant une grosse question. Ayant un peu plus d'expérience dans l'utilisation de XCode (mais pas forcément de la programmation en Cocoa/ObjC), je me pose beaucoup de questions sur la gestion de la mémoire et j'ai besoin de réponses simples. En gros si vous répondez, essayez de vous adresser à qqun qui n'a jamais programmé :P. Je saisis les grands principes mais la subtilité.
Si dans mon .H j'ai cela
Ensuite dans mon .M j'ai cela
Je voulais savoir si cela était la bonne démarche ? Donc pour résumé pas de @propoerty pour un NSInteger ou un int mais par contre pour un NSNumber il en faudrait un.
Et ensuite pour le NSString, il faut absolument mettre self.webtitle = @"".
Ayant eu beaucoup de crash dus à des self manquants et après les avoir mis ça ne crashait plus, je voulais savoir si j'employais donc la bonne méthode.
Merci
neospirit
Si tu comprends ce code, tu comprends tout: il n'y a pas de magie. ça explique aussi pourquoi écrire [tt]self.webTitle = nil[/tt] relâche la mémoire.
Ceci dit, ceci est une simplification. D'après nos informations, le code généré serait plutôt celui-ci:
En effet, appeler un setter génère des notifications Key-Value Observing, et il semble que l'objet soit relâché par l'autorelease pool, et non pas immédiatement.
Si on écrit:
deux erreurs sont commises. En effet :
- l'objet actuel ne retient pas title. Quand unAutreObjet ne le retiendra plus, webTitle pointera sur un objet qui ne sera plus présent en mémoire => plantage.
- l'ancien objet pointé par webTitle n'est plus référencé, mais n'est pas désalloué => fuite mémoire.
En général, il ne faut pas l'utiliser pour des objets, puisque l'objet n'est pas retenu, et qu'on a donc peu de certitude qu'il sera encore présent en mémoire quand on fera appel à lui.
Par contre, pour les types C (c'est à dire non-objets, comme int, char, float, CGRect, etc.), il faut bien utiliser assign.
Du coup, il faut aussi mettre les @synthesize dans le .M pour ces variables ?
Dans mon appli j'ai un SQLiteManager avec des NSInteger. Je les ai mis en "assign" pour que 3 ViewController tierces puissent accéder à leurs valeurs. Cela changerait-il donc quelque chose si je les mets en retain comme tout le reste ?
Et donc aussi mettre des @synthesize sur les NSInteger ?
Avant il te faut comprendre la notion d'encapsulation et des getter/setter
utilise les notions que tu maitrises, et pas les "trucs" vu ou lu qque part.
par exemple, nonatomic, ton application en a t'elle reelement besoin?
@cyrano : euh je sais pas si j'en ai besoin, mais pour l'instant je l'ai vu dans tous les tutos et bout de code que j'ai pu rencontrer, donc par défaut je le mets, mais si y'en a pas besoin...
dans le meme ordre d'idee que le retain sur un int
Que pensez vous du nonatomic sur un int?
(Mettre une propriété int en retain, ne génère-t-il par une erreur ? C'est le cas pour une propriété en copy).