copy, new, [[ ... alloc] init]

Philippe49Philippe49 Membre
février 2008 modifié dans API AppKit #1
Quelle différence voyez-vous entre
    stringValue=[[NSString alloc] initWithString:@une string];
et
    stringValue=[@une string copy];
Dès lors, à  quoi peut servir la 1ère méthode ?

Essai

NSString * str=[[NSString alloc] initWithString:@coucou];
NSString * str1=[str copy];
NSString * str2=[@coucou copy];
NSString * str3=[[NSString alloc] initWithString:str];
NSLog(@%p %p %p %p,str,str1,str2,str3);


resultat : 0x2030 0x2030 0x2030 0x2030



De même, la littérature utilise très rarement la méthode [.. new] lui préférant [[... alloc] init]


Réponses

  • février 2008 modifié #2
    2 éléments "faussent" ton test.

    - 1. tu n'utilises que des NSString et pas de NSMutableString (et copy et pas de mutableCopy) ( [[NSMutableString alloc] initWithString:@coucou] fait quelque chose de différent de la simple copie). Si tu sous-classes NSString, l'alloc init te permettra de t'assurer que tu as bien la classe dont tu as besoin.
    - 2. tu utilises des strings initilialisée à  partir de @";". Il se fait que le compilateur est un peu malin et ne "génère" qu'une instance pour toutes les strings identiques dans un même fichier.

    Sinon oui, il y a des méthodes qui font double emploi. Dans le cas que tu donnes, copy fait aussi double emploi avec retain,...
  • Philippe49Philippe49 Membre
    16:57 modifié #3
    dans 1201967773:

    - 1. tu n'utilises que des NSString et pas de NSMutableString (et copy et pas de mutableCopy).

    Oui ce serait différent avec des NSMutableString ,  copy créerait une nouvelle instance.

    dans 1201967773:

    - 2. tu utilises des strings initilialisée à  partir de @";". Il se fait que le compilateur est un peu malin et ne "génère" qu'une instance pour toutes les strings identiques dans un même fichier.


    NSString * str=[[NSString alloc] initWithFormat:@coucou %d,2008];
    NSString * str1=[str copy];
    NSString * str3=[[NSString alloc] initWithString:str];

    même résultat (chaà®nes dans une autre zone car l'allocation est faite lors de l'exécution)
    0x10b070 0x10b070 0x10b070


    La question que je me pose en fait, c'est ce qu'il faut privilégier dans une méthode comme
    [[maClasse alloc] initWithName:aName];

    name=[aName copy] me semble le plus clair, mais je suis retenu (retained) parce que j'ai toujours vu dans ce genre de cas un truc du type alloc-init. Il faut dire que pour les NSString cela revient au même mais pour des classes plus complexes, le copy reste plus dangereux.

  • 16:57 modifié #4
    J'avais édité mon message, tu n'as peut être pas la correction.

    Le passage par alloc/init permet de "convertir" si nécessaire en une autre sous-classe; ce ne qui serait pas permis par copy/mutableCopy.
  • février 2008 modifié #5
    dans 1201969339:
    même résultat (chaà®nes dans une autre zone car l'allocation est faite lors de l'exécution)


    En fait pour la petite histoire: [tt][NSString alloc][/tt] renvoie toujours un singleton. Ce que tes tests montrent, c'est que dans [tt]-initWithString:[/tt], l'implémentation par défaut vérifie la nature de l'objet passé en argument et renvoie le dit objet avec un [tt]-retain[/tt] si la classe est de l'objet passé en argument NSString.

    Tu as aussi là  un bon exemple du pourquoi du:
    [tt]str = [[NSString alloc] init];[/tt]

    et pas
    [tt]str = [NSString alloc];
    [str init]; [/tt]

    Donc tu prends en fait une classe avec une implémentation un peu particulière, ne tire donc pas de conclusions trop hâtives.
Connectez-vous ou Inscrivez-vous pour répondre.