Il est possible que ces exemples utilisent le conserver car l'exemple de code alloue par programme et initialise un UILabel, puis l'ajoute à l'UIView. C'est le cas pour de nombreux exemples, car apprendre à utiliser Interface Builder n'est souvent pas leur but. Le deuxième exemple (aucune propriété et aucune synthèse) avec l'IBOutlet est utilisé lorsque le développeur 'affecte' le UILabel (bouton, vue, etc.) dans l'interface Builder - en faisant glisser l'objet IBOulet vers l'étiquette ou une autre vue composant. À mon avis, l'action glisser-déposer précédente (Étiqueter sur la vue) ajoute également la sous-vue, l'étiquette à une vue - et ainsi de suite. L'étiquette est conservée par une vue; une vue est conservée par Window; La fenêtre est conservée par le propriétaire du fichier. Le propriétaire du fichier est généralement votre document qui est démarré dans le main.
Vous remarquerez que lorsque vous parcourez votre programme (en ajoutant un awakeFromNib
- (void)awakeFromNib
{
[fooLabel blahblah];
}
que fooLabel dispose déjà d'une adresse mémoire.
C'est parce que l'étiquette a été initialisé à partir d'un ensemble de fichiers (le fichier nib) en utilisant non init mais initWithCoder qui désérialise essentiellement le flux de fichiers à un objet - et ensuite définit la variable IBOutlet. (Nous parlons toujours de la méthode IBOutlet.)
Notez également que le susdit iOS moi thod utilise la méthode Key Value
call [object setValue:outletValue forKey:@"<OutletName>"]
qui est le modèle Observer/Observable. Ce modèle nécessite que l'objet Observable référence chaque observateur dans un ensemble/tableau. Un changement de valeur va itérer l'ensemble/tableau et mettre à jour tous les observateurs. Cet ensemble conservera déjà chaque observateur ainsi le manque de retenue dans iOS.
En outre et le reste est la spéculation.
Il semble que les cas lorsque vous utilisez Interface Builder ne puis
@property (nonatomic, retain) IBOutlet UILabel *fooLabel;
devrait peut-être changé à
@property (nonatomic, weak) IBOutlet UILabel *fooLabel;
ou @property (nonatomic, assigner) IBOutlet UILabel * fooLabel;
Et puis il n'a pas besoin d'être libéré dans une méthode dealloc. De plus, il répondra aux exigences OSX et iOS.
C'est basé sur la logique et je pourrais manquer quelques pièces ici. Néanmoins, cela peut ne pas être important si la vue est persistante pendant toute la durée de vie de votre programme. Alors qu'une étiquette dans une boîte de dialogue modale (ouvrir, fermer, ouvrir, fermer) peut en fait avoir sur-retenu et fuite par cycle. Et c'est parce que (spéculation encore) chaque boîte de dialogue fermée est sérialisée dans un système de fichiers et persiste ainsi x, position y et taille, avec ses sous-vues, etc Et ensuite désérialisé ... à la prochaine session ouverte (Opposé à dire minimiz ou caché.)
Salut Jon, Merci pour la réponse détaillée! Très utile –
que se passe-t-il si le nom de la variable est différent du nom de la propriété? Est-ce important si différent? –
Le nom "OutletName" ci-dessus est défini comme étant tout ce qui est à côté du mot clé "IBOutlet" dans le code source. Si IBOutlet est dans @property, peu importe la variable d'instance nommée car un setter sera trouvé. Si pour une raison quelconque un setter n'existait pas, une exception serait levée lors de la connexion de la prise. Si le mot-clé IBOutlet est sur la variable d'instance et qu'un setter existe avec un nom qui ne correspond pas, le setter ne sera pas appelé. –