2010-08-14 4 views
2

Une chose qui m'inquiète est que je crée deux ints, mais ne les libère pas. Serait-il préférable de les faire NSIntegers?Est-ce que ce code Objective-C fuit la mémoire?

-(void) flipCoin { 

    int heads = [headsLabel.text intValue]; 
    int tails = [tailsLabel.text intValue]; 

    if (random() %2 ==1) 
    { 
     heads++; 
    } 
    else { 
     tails++; 
    } 

    headsLabel.text = [NSString stringWithFormat:@"%d", heads] ; 
    tailsLabel.text = [NSString stringWithFormat:@"%d", tails]; 

} 

Répondre

2

int est ce que l'on appelle un type primitif. Ce n'est pas un pointeur vers un objet Objective-C, vous ne pouvez donc pas le libérer. Vous ne pouvez même pas envoyer de message. NSInteger est également un type primitif dans le sens où il s'agit d'un typedef à un type primitif (long habituellement). Donc, vous ne pouvez pas libérer cela non plus.

De quoi avez-vous besoin pour sortir?Vous devez libérer tout objet obtenu en envoyant new, alloc ou une méthode contenant une copie. Vous devez également libérer les objets que vous avez envoyés. Donc, toutes les variables locales dans les conditions suivantes doivent être libérés:

-(void) foo 
{ 
    NSString* aString = [[NSString alloc] init]; 
    NSString* aString2 = [aString copy]; 
    NSString* aString3 = [someOtherString retain]; 
    NSString* aString4 = [@"some string" copy]; 
} 

NB en raison des détails de mise en œuvre, vous auriez fait sortir sans relâcher le aString4 mais vous n'avez pas besoin de vous en inquiéter.

2

Non, vos heads et tails variables sont locales et stockées sur la pile. Cela ne provoquera pas de fuite. Vos deux affectations NSString près du bas sont créées à l'aide de constructeurs de commodité et seront automatiquement libérées pour vous.

2

Tous les types de données par défaut (int, char, BOOL, etc) sont gérés automatiquement pour vous, et ne pas (et ne peuvent) être libérés (pour toutes fins utiles). NSInteger s se comportent de la même manière, car ils ne sont que signed int s (ou signed long s sur les machines 64 bits).

objets vous initialisez, cependant, comme NSString ou NSArray devront généralement être libérés (à moins qu'ils ne sont autoreleased, comme les NSString s au bas de votre code). Si jamais vous appelez -alloc et -init sur quelque chose, vous devrez le libérer plus tard. Si jamais vous doutez qu'une méthode renvoie un objet autoreleased, lisez simplement la documentation (elle vous le dira). En outre, si vous voulez lire sur la gestion de la mémoire, il y a beaucoup de sources merveilleuses qui vous apprendront (Google est un bon point de départ!), Et si jamais vous pensez que votre code perd de la mémoire, lancez-le à travers les Instruments, et vous serez en mesure de dire ...

7

Comme notes, les variables locales sont allouées dans le cadre de la pile en cours. Dès que l'appel de fonction en cours revient, la pile est "sautée" et la mémoire occupée pour l'appel en cours n'est pas libérée tant qu'elle est abandonnée, jusqu'à ce qu'elle soit écrasée par l'appel suivant qui est poussé dans cette partie de la pile.

Alors, pourquoi devons-nous libérer des variables comme ceci:

MyClass *myObject = [[MyClass alloc] init]; 

Eh bien, vous ne fait pas à vous soucier de « myObject ». Il est sur la pile, tout comme vos ints, et il sera nettoyé lorsque l'appel en cours se terminera. Ce dont vous avez à vous soucier est la mémoire que myObject - qui est un pointeur - indique. C'est quelque part sur le tas. Construire un objet implique de demander à l'exécution d'une place semi-permanente de le mettre; ce processus renvoie une adresse mémoire que votre pointeur stocke.

alloc et release sont idiomes Objective-C qui a largement remplacer les fonctions de C malloc() et free(), mais tous, finalement, demandent l'ordinateur de mettre de côté la mémoire sur le tas, et tous que la mémoire doit finalement être renvoyé, soit par un pool d'autorelease, un message release ou un appel free().

+1

+1 pour cette phrase: "Eh bien, vous n'avez pas à vous soucier de" myObject ", il est sur la pile, tout comme vos ints, et il sera nettoyé quand l'appel en cours se terminera.". Ce fait est important de mentionner puisque beaucoup de gens inexpérimentés ne l'obtiennent pas. – monoceres

+0

Une autre chose qui mérite d'être soulignée: ints et autres valeurs des types primitifs ne sont pas des objets Cocoa ou CF, c'est pourquoi (1) vous ne les gérez pas de la même façon que les objets Cocoa et CF (ils n'ont pas de rétention count), (2) vous ne pouvez leur envoyer aucun message, et (3) vous ne pouvez pas les placer directement dans des objets de collection Cocoa ou CF; vous devez les placer dans des objets de valeur tels que NS/CFNumber ou NS/CFString et les placer dans vos collections. NSInteger, NSUInteger, CFIndex et CGFloat ne sont que d'autres noms (typedefs) de types primitifs, donc tout ceci est également vrai pour eux. –

+0

Si vous créez un objet avec alloc init dans un appel de fonction, devez-vous le libérer dans cet appel de fonction ou le traiter automatiquement comme les variables locales? –

Questions connexes