Compteur de référence à  2 sur [[NSNumber alloc] init]

13:23 modifié dans API AppKit #1
Bonjour,

Le thème de week-end étant la gestion de la mémoire, je serais curieux de savoir pourquoi dans ce simple cas le compte de référence vaut 2...

NSNumber *number=[[NSNumber alloc] initWithInt:10];
NSLog(@retainCount:%d,[number retainCount]);

Merci.

Réponses

  • NoNo Membre
    13:23 modifié #2
    Je ne sais plus où cela est marqué dans la doc Apple, mais les NSNumber fréquents sont précréés.
    Donc si tu alloues 2 objets NSNumber avec le même nombre 10, tu auras le même pointeur.

    Comme il est déjà  créé avant ton alloc () , tu auras forcément un refcount supérieur à  1 : c'est une sorte de shared object propre à  l'optimisation de NSNumber.
  • NoNo Membre
    13:23 modifié #3
    dans 1220200986:

    Je ne sais plus où cela est marqué dans la doc Apple
    [...]

    Ah oui, en fait faut voir la doc sur CFNumber, puisque NSNumber n'est qu'une toll free bridged class.


    Note: In order to improve performance, some commonly-used numbers (such as 0 and 1) are uniqued. You should not expect that allocating multiple CFNumber instances will necessarily result in distinct objects.


  • Philippe49Philippe49 Membre
    septembre 2008 modifié #4
    Un petit essai
    #import &lt;Foundation/Foundation.h&gt;<br />#define VALUE 10<br />int main (int argc, const char * argv&#91;]) {<br />	NSAutoreleasePool * pool=[[NSAutoreleasePool alloc] init];<br />	NSString * string=[[NSString alloc] initWithFormat:@&quot;Hello World %d&quot;,2008];	<br />	NSNumber * number1=[NSNumber numberWithInt:VALUE];<br />	NSIndexPath * indexPath=[NSIndexPath  indexPathWithIndex:2]; <br />	printf(&quot;string : %u , number : %u, indexPath : %u&#092;n&quot;,[string retainCount],[number1 retainCount],[indexPath retainCount]);<br />	NSNumber * number2=[[NSNumber alloc] initWithInt:VALUE];<br />	printf(&quot; %s , number : %u&#092;n&quot;,number2==number1 ? &quot;Equals&quot;:&quot;Non Equals&quot;,[number2 retainCount]);<br />	[pool drain];<br />	return 0;<br />}
    


    Résultat :
    Avec #define VALUE 2008
    % gcc pgm.m -o pgm -framework Foundation
    % pgm
    string : 1 , number : 1, indexPath : 3
    Non Equals , number : 1
    %


    Avec #define VALUE 10 par contre, on a :
    % gcc pgm.m -o pgm -framework Foundation
    % pgm
    string : 1 , number : 2, indexPath : 3
    Equals , number : 3
    %


  • août 2008 modifié #5
    Parfait merci.
  • AliGatorAliGator Membre, Modérateur
    13:23 modifié #6
    dans 1220208514:

    Un petit essai
    // ...<br />printf(&quot; %s , number : %u&#092;n&quot;,number2==number1 ? &quot;number1≠number2&quot;:&quot;number1=number2&quot;,[number2 retainCount]);<br />
    

    Heu tu t'es pas gouré dans l'utilisation de ton opérateur ternaire là  ? si (number2==number1) est VRAI, alors il affiche qu'il est différent... et s'ils sont différents, il affiche qu'ils sont égaux :P
    De plus dans ta 2e exécution quand tu dis remplacer 2008 par 10, tu dis que ça t'affiche "Equals" et pas "number1=number2" :)
    Y'a emmêlage de pinceaux, là  :)

    --

    Sinon je propose qu'à  chaque fois que Philippe49 répond à  une question les forums par un "Un petit essai" suivi d'un bout de code (extrait d'un test dans un FoundationTool avec juste [tt]main[/tt]), que celui qui a posé ladite question lui offre au moins une petite tournée :p Et que tout le monde puisse en profiter, au passage ;D
    Parce que c'est pas pour dire mais ça arrive vachement souvent quand même :P
  • août 2008 modifié #7
    --
  • Philippe49Philippe49 Membre
    13:23 modifié #8
    Oui je n'avais pas corrigé le code (les résultats étaient bons naturellement) ... C'est fait

    Quand à  m'offrir un coup à  boire, il ne faut pas hésiter ...  :p :p
Connectez-vous ou Inscrivez-vous pour répondre.