Question

Je commence à mieux comprendre la gestion de la mémoire dans objective-c, mais il y a quelque chose que je ne comprends pas. Ceci est une déclaration de propriété:

@property (nonatomic, retain)UILabel *myLabel;

et c'est son setter synthétisé invisible (je pense):

- (void)setMyLabel:(UILabel *)newValue {
    if(myLabel != newValue) {
        [myLabel release];
        myLabel = [newValue retain];
    }
}

Ce qui vous épargne le travail de conservation et de chargement à chaque fois, mais disons que je mets ma propriété pour la première fois, elle n’a pas encore été attribuée, son nombre de références est donc 0, non? Donc je fais

UILabel *tempLabel = [[UILabel alloc] init];
self.myLabel = tempLabel;
[tempLabel release];

Je ne suis pas vraiment sûr de ce qui se passe là-bas, lorsqu'il ne libère rien, mais que la propriété a déjà une valeur et que nous la définissons. Dans le setter, il est d'abord libéré. Cela ne fait-il donc pas disparaître la situation? Si son nombre de références est égal à un, puis dans le sélecteur, comment est-il conservé pour rester défini sur la nouvelle valeur conservée?

Merci !!

Était-ce utile?

La solution

Je pense que vous confondez les objets et les références. Une propriété est une référence à un objet, pas à l'objet lui-même. Lorsque vous définissez ou désélectionnez une propriété, elle envoie, conserve et libère les objets sur lesquels elle pointe, mais la référence elle-même fait partie de l'objet dans lequel se trouve la propriété (dans ce cas, self).

Il pourrait être utile de lire des articles tels que pointeurs et lvalues ??.

Autres conseils

La valeur initiale de myLabel est nil, votre première affectation à la propriété, c'est-à-dire

self.myLabel = tempLabel;

publiera nil, c'est-à-dire [nil release]. En Objective C, l’envoi d’un message à nil est un non-op, cela ne fera donc rien.

De même, dans votre méthode dealloc, vous devriez avoir:

[myLabel release];

Qui libérera myLabel si la propriété a déjà été affectée, en équilibrant la [newValue rétention] dans le sélecteur. Si la propriété n'a jamais été affectée, elle sera toujours nulle et, encore une fois, la [version nil] sera interdite.

Lisez les règles de gestion de la mémoire pour les règles exactes sur le moment où vous devez conserver / libérer des objets.

L'objet va "disparaître". (c.-à-d. être désalloué) lorsque tous les droits de propriété ont été abandonnés. Autrement dit, lorsque (ou peu de temps après) tous les appels d'allocation / copie / nouveaux appels ont été équilibrés avec des appels de libération / libération automatique.

Je suis également relativement nouveau dans Objective-C, mais j'aimerais essayer d'y répondre pour réaffirmer ma compréhension.

  

Disons que je mets ma propriété pour la première fois, elle n’a pas encore été attribuée, donc son nombre de références est 0, non?

Oui, le nombre de retenues est 0.

  

Dans le passeur, il est d'abord libéré. Cela ne fait-il donc pas disparaître la situation?

Il soustrait 1 du nombre de retenues de myLabel . Si le nombre de conservations de myLabel atteint 0, les données ou objets pointés par la variable myLabel seront libérés de la mémoire.

  

Si son nombre de références est égal à un, puis dans le sélecteur, il est libéré, comment reste-t-il dans les environs pour qu'il soit défini sur la nouvelle valeur conservée?

Dans ce scénario, les données myLabel pointées seront libérées (le nombre de conservation seront 0) et myLabel pointera ensuite sur nil (vide). La variable est définie dans la classe et sera toujours disponible pour accepter les messages de cet utilisateur. Ainsi, les nouvelles données peuvent être affectées à myLabel si le code de conservation de myLabel est 0. ou 100.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top