Quant à "weak" vs. "strong" ("référence faible" vs. "référence forte"), tu peux voir une référence forte comme une laisse entre un maà®tre et son chien (et une référence faible comme juste un regard du chien vers son maà®tre, mais sans laisse pour les lier fortement. Ou juste le nom du maà®tre sur la médaille du chien, pour qu'on puisse retrouver le Maà®tre à partir du Chien, mais sans lien physique qui l'enchaà®ne pour autant).
Si le Maitre a une référence forte sur le Chien (il le tient en laisse), ça veut dire qu'il le retient. C'est lui qui "possède" l'objet et le maintient en vie. Tant que le maà®tre est là , il retient le chien (il le tient en laisse). Si le maà®tre s'en va, et lâche ainsi la laisse, le chien ne sera plus retenu par personne et pourra aussi s'en aller. Donc le fait que le Maà®tre ait une référence forte sur le Chien fait que tant que le Maà®tre vit, il retient le Chien qui ne va être maintenu en vie aussi.
Par contre le Chien va plutôt avoir typiquement une référence faible vers le Maà®tre. Il connaà®t son maà®tre, quand on a une instance de l'objet Chien, on peut savoir (en lisant sa médaille) qui est son Maà®tre. Mais le Chien ne retient pas le Maà®tre, ce n'est pas lui qui tient son Maà®tre en laisse. Le chien ne retient pas le maà®tre et ne l'empêche pas de disparaà®tre.
De même, si plusieurs objets "Maà®tre" ont une référence forte vers un même objet Chien c'est un peu comme si le chien était attaché par plusieurs laisses. Certains maà®tres peuvent disparaà®tre et être libéré de la mémoire, mais tant qu'il y aura au moins un Maitre qui tient ce chien en laisse, le chien restera lui aussi en mémoire. Autrement dit, tant qu'il existe un objet M ayant une référence forte vers l'objet C, l'objet C restera en mémoire.
Par contre si plus aucun objet Maitre n'a de référence forte sur l'objet Chien, que le Chien n'a donc plus aucune référence strong qui pointe sur lui, (et que s'il a encore des références qui pointent sur lui ce ne sont que des références weak et pas strong) alors il n'a plus rien qui le retient en mémoire donc il va repasser à nil. C'est ce que t'explique Joanna quand elle te dit que ton objet n'a peut-être que des références weak mais aucune référence strong sur ton objet donc si personne ne le retient avec un strong il va être libéré.
En général quand deux objets se référencent l'un-l'autre, pour éviter qu'ils se retiennent mutuellement et du coup ne se libèrent jamais, comme expliqué par Draken on en choisit un qui retient l'autre en strong, et l'autre retient le premier en weak. C'est en général plutôt celui qui pourrait agir comme "parent" ou "conteneur" qui retient ce qui s'identifie plutôt comme "enfant" ou "contenu".
Par exemple, dans une relation "Livre" -> "Pages", c'est plutôt le Livre qui va retenir (= "avoir une référence strong vers") ses Pages qui le composent, et chaque objet Page ne va avoir qu'une référence "weak" vers son Livre parent.
Ou encore dans une relation Voiture -> Roues, c'est la Voiture qui aura une référence strong vers ses 4 roues, et chaque roue aura une référence weak vers la Voiture à laquelle elle appartient. Comme ça si la voiture est détruite, plus personne ne retient les roues (à part si tu avais une *autre* référence strong qui faisait qu'un autre objet ou une autre variable que ta voiture les retenait, bien sûr) et les roues sont détruites aussi, par contre si tu détruit les roues, ça va pas pour autant détruire la voiture.
Merci pour vos efforts, c'est sympa de me remettre un peu les pendules à l'heure.
Je pense avoir bien compris.
Juste deux petites questions :
1-
NB : Note d'ailleurs au passage que ce n'est donc pas *exactement* la même chose qu'avant, car dans ce cas il considère que ta variable est de type non-optional ("UIView") alors qu'en la typant explicitement avec ": UIView!" tu lui dis que c'est une "implicitly-unwrapped-optional" donc une "UIView!" et pas juste une "UIView"...
Donc, dans quel cas dois-je mettre
var labelsVignettesPatientA1: UILabel = UILabel()
plutôt que
var labelsVignettesPatientA1 = UILabel()
2-
J'ai adoré l'histoire du maà®tre et son chien. Très belle histoire, et pleine de rebondissements. ça m'a mis de bonne humeur pour toute cette journée ensoleillée. Merci.
Par contre, je n'ai pas de liaison entre mes variables. Elles sont indépendantes. A part, évidemment, celles que j'utilise pour des calculs (genre x = 3y + 17z etc). Je n'ai pas d'objets qui se référencent mutuellement. Je n'ai donc pas à me soucier de "weak sans un strong" ?
Mais en relisant cela (Draken)
Cela arrive chaque fois qu'un objet possède un lien sur son "supérieur". Par exemple une vue avec une référence sur son contrôleur.
Je me dis que je suis en fait loin du compte. ça me fait peur.
Je me suis mal exprimé. Habituellement une vue n'as pas de lien vers son supérieur. Cela peut arriver parfois, quand la vue a besoin de faire remonter une information vers son contrôleur. Dans ce cas, il faut coder le mécanisme soi-même et utiliser un attribut weak.
Si oui, c'est normal que ça plante. Et c'est exactement ce que disais le nounours. La méthode UILabel() fabrique un label quelque part dans la mémoire, sans le relier à rien. Il faut stocker son adresse pour le "retenir", lui mettre une "laisse" comme dit Ali. Si cette adresse est écrite dans une variable weak, donc une variable sans "laisse", iOS "pense" que l'objet n'est pas utilisé et le détruit.
class ViewController: UIViewController {
weak var monLabel:UILabel!
override func viewDidLoad() {
super.viewDidLoad()
monLabel = UILabel(frame: CGRectMake(0, 0, 200, 200))
// monLabel est détruit à ce stade, car il n'est pas retenu par une "laisse"
// il prend alors la valeur nil
// Il se passe des choses ici, même si c'est invisible dans le code source
// ça plante ici parce que monLabel vaut nil
self.view.addSubview(monLabel)
}
}
Je me suis mal exprimé. Habituellement une vue n'as pas de lien vers son supérieur. Cela peut arriver parfois, quand la vue a besoin de faire remonter une information vers son contrôleur. Dans ce cas, il faut coder le mécanisme soi-même et utiliser un attribut weak.
En fait ça arrive tout le temps, mais de manière transparente. Tous les composants graphiques interactifs ont besoin d'un lien vers le contrôleur pour lui signaler les événements (boutons, sliders, scrollView, etc..). Ils stockent ce lien en interne sous la forme d'une variable weak. C'est le storyboard ou la méthode addTarget() qui s'occupe de ça.
Réponses
Si le Maitre a une référence forte sur le Chien (il le tient en laisse), ça veut dire qu'il le retient. C'est lui qui "possède" l'objet et le maintient en vie. Tant que le maà®tre est là , il retient le chien (il le tient en laisse). Si le maà®tre s'en va, et lâche ainsi la laisse, le chien ne sera plus retenu par personne et pourra aussi s'en aller. Donc le fait que le Maà®tre ait une référence forte sur le Chien fait que tant que le Maà®tre vit, il retient le Chien qui ne va être maintenu en vie aussi.
Par contre le Chien va plutôt avoir typiquement une référence faible vers le Maà®tre. Il connaà®t son maà®tre, quand on a une instance de l'objet Chien, on peut savoir (en lisant sa médaille) qui est son Maà®tre. Mais le Chien ne retient pas le Maà®tre, ce n'est pas lui qui tient son Maà®tre en laisse. Le chien ne retient pas le maà®tre et ne l'empêche pas de disparaà®tre.
De même, si plusieurs objets "Maà®tre" ont une référence forte vers un même objet Chien c'est un peu comme si le chien était attaché par plusieurs laisses. Certains maà®tres peuvent disparaà®tre et être libéré de la mémoire, mais tant qu'il y aura au moins un Maitre qui tient ce chien en laisse, le chien restera lui aussi en mémoire. Autrement dit, tant qu'il existe un objet M ayant une référence forte vers l'objet C, l'objet C restera en mémoire.
Par contre si plus aucun objet Maitre n'a de référence forte sur l'objet Chien, que le Chien n'a donc plus aucune référence strong qui pointe sur lui, (et que s'il a encore des références qui pointent sur lui ce ne sont que des références weak et pas strong) alors il n'a plus rien qui le retient en mémoire donc il va repasser à nil. C'est ce que t'explique Joanna quand elle te dit que ton objet n'a peut-être que des références weak mais aucune référence strong sur ton objet donc si personne ne le retient avec un strong il va être libéré.
En général quand deux objets se référencent l'un-l'autre, pour éviter qu'ils se retiennent mutuellement et du coup ne se libèrent jamais, comme expliqué par Draken on en choisit un qui retient l'autre en strong, et l'autre retient le premier en weak. C'est en général plutôt celui qui pourrait agir comme "parent" ou "conteneur" qui retient ce qui s'identifie plutôt comme "enfant" ou "contenu".
Merci pour vos efforts, c'est sympa de me remettre un peu les pendules à l'heure.
Je pense avoir bien compris.
Juste deux petites questions :
1-
Donc, dans quel cas dois-je mettre
plutôt que
2-
J'ai adoré l'histoire du maà®tre et son chien. Très belle histoire, et pleine de rebondissements. ça m'a mis de bonne humeur pour toute cette journée ensoleillée. Merci.
Par contre, je n'ai pas de liaison entre mes variables. Elles sont indépendantes. A part, évidemment, celles que j'utilise pour des calculs (genre x = 3y + 17z etc). Je n'ai pas d'objets qui se référencent mutuellement. Je n'ai donc pas à me soucier de "weak sans un strong" ?
Mais en relisant cela (Draken)
Je me dis que je suis en fait loin du compte. ça me fait peur.
Bon, ben malheureusement, je me retrouve confronté au même problème qu'au départ. Dès que je rajoute weak, ça part en sucette.
ça, ça marche correctement
puis plus loin dans ma fonction
Mais dès que je met le weak - Toujours l'erreur fatale
J'ai tout essayé - sur les conseils de Xcode - les ? les !
j'ai même refait avec
Puis
Toujours la même erreur au lancement de l'appli.
Et également sur les conseils de xcode
Puis
Toujours la même erreur au lancement de l'appli.
ça aussi ça plante et même erreur
(D'après la page apple) -> (weak var tenant: Person?)
puis
En gros, dès que je met un weak, impossible de faire tourner le projet
Je me suis mal exprimé. Habituellement une vue n'as pas de lien vers son supérieur. Cela peut arriver parfois, quand la vue a besoin de faire remonter une information vers son contrôleur. Dans ce cas, il faut coder le mécanisme soi-même et utiliser un attribut weak.
Est-ce que ton code ressemble à ça :
Si oui, c'est normal que ça plante. Et c'est exactement ce que disais le nounours. La méthode UILabel() fabrique un label quelque part dans la mémoire, sans le relier à rien. Il faut stocker son adresse pour le "retenir", lui mettre une "laisse" comme dit Ali. Si cette adresse est écrite dans une variable weak, donc une variable sans "laisse", iOS "pense" que l'objet n'est pas utilisé et le détruit.
Comme nous disions, si tu n'as qu'un weak, l'objet mourra dès qu'il est né.
En fait ça arrive tout le temps, mais de manière transparente. Tous les composants graphiques interactifs ont besoin d'un lien vers le contrôleur pour lui signaler les événements (boutons, sliders, scrollView, etc..). Ils stockent ce lien en interne sous la forme d'une variable weak. C'est le storyboard ou la méthode addTarget() qui s'occupe de ça.