Tableau en tant que constante

6ix6ix Membre
09:00 modifié dans API AppKit #1
Salut tout le monde,

Question qui peut paraà®tre bête, et pourtant, j'ai des difficultés... Dans mon application, j'aimerais déclarer un tableau (contenant plusieurs valeurs NSNumber) en tant que constante.

J'ai déjà  un fichier Constants.h (contenant d'autres constantes avec #define x y), et voilà  ce que j'ai fait pour mon tableau, mais j'ai des erreurs lors de l'accès à  celui-ci:
<br />@interface Constants : NSObject {}<br /><br />// Distance filter<br />+ (NSArray*) kFilterDistance;<br /><br />@end<br /><br />#import &quot;Constants.h&quot;<br />@implementation Constants<br /><br />/** Create an array of (filter) distances. */<br />+ (NSArray *)kFilterDistance {<br />&nbsp; &nbsp; static NSArray* distances = nil;<br />&nbsp; &nbsp; if(distances == nil) {<br />&nbsp; &nbsp; &nbsp; &nbsp; distances = [NSArray arrayWithObjects:[NSNumber numberWithInt:0.2],<br />			[NSNumber numberWithInt:0.5],<br />			[NSNumber numberWithInt:2.0],<br />			[NSNumber numberWithInt:5.0],<br />			[NSNumber numberWithInt:10.0],<br />			nil];<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return distances;<br />}<br />@end<br />


Par exemple, en appelant [[Constants kFilterDistance] count].

Que fais-je de faux? Ou alors y a-t-il une autre manière de déclarer un talbeau comme constante?

Merci d'avance!

Réponses

  • schlumschlum Membre
    09:00 modifié #2
    Le tableau est autoreleased avec ce code... Il ne va rester en mémoire qu'un cycle de runLoop.
  • 6ix6ix Membre
    09:00 modifié #3
    Oui, mais logiquement il devrait alors être créé à  chaque appel de la méthode kFilterDistance... non?

    Dans le cas contraire, quelle serait la meilleure manière de créer un tableau en tant que constante?
  • Philippe49Philippe49 Membre
    novembre 2008 modifié #4
    La variable distances étant déclarée en static (static NSArray* distances = nil;) a une durée de vie illimitée.
    Mala nous a signalé une belle solution à  ce problème :
    Faire un singleton ,
    Faire une méthode - (NSArray *)kFilterDistances codée comme tu l'as fait
    (ou créer une variable au singleton)

    Tu trouveras de la doc sur les singletons dans les guides de base.
  • 6ix6ix Membre
    09:00 modifié #5
    Ok je vois (j'ai déjà  fait des singleton).

    Donc j'obtiendrais mon tableau par un appel de la sorte, si je ne me trompe pas:
    [[Constants sharedConstants] kFilterDistances]
    

    Ce qui me permettrait ensuite d'accéder à  d'autres constantes de la même manière.

    Je dois dire que je n'ai pas une grosse expérience en Objective-C, je ne connais donc pas vraiment la manière la plus élégante de déclarer ces constantes.

    Je vais essayer ça, merci.
  • Philippe49Philippe49 Membre
    novembre 2008 modifié #6
    Tu peux aussi essayer comme cela (mais je préfère la version du singleton) :

    =============================================
    @interface Constants : NSObject {}

    // Distance filter
    + (NSArray*) kFilterDistance;

    @end
    =============================================
    #import "Constants.h"

       static NSArray* distances = nil;

    @implementation Constants

    /** Create an array of (filter) distances. */
    + (NSArray *)kFilterDistance {

       if(distances == nil) {
           distances = [NSArray arrayWithObjects:[NSArray alloc] initWithObjects:[NSNumber numberWithInt:0.2],
    [NSNumber numberWithInt:0.5],
    [NSNumber numberWithInt:2.0],
    [NSNumber numberWithInt:5.0],
    [NSNumber numberWithInt:10.0],
    nil];
       }
       return distances;
    }
    @end

  • Philippe49Philippe49 Membre
    09:00 modifié #7
    dans 1227436890:

    Ok je vois (j'ai déjà  fait des singleton).

    Donc j'obtiendrais mon tableau par un appel de la sorte, si je ne me trompe pas:
    [[Constants sharedConstants] kFilterDistances]
    

    Ce qui me permettrait ensuite d'accéder à  d'autres constantes de la même manière.


    oui
  • AliGatorAliGator Membre, Modérateur
    09:00 modifié #8
    dans 1227436918:

    Tu peux aussi essayer comme cela (mais je préfère la version du singleton) :
    ...
    Heu avec alloc/initWithArray et non arrayWithArray, non ? Histoire que le tableau ne se détruise pas à  la fin de la RunLoop... (sinon ça sert pas à  grand chose de le mettre en static et de toute façon s'il se détruit la variable kFilterDistances ne se remettra pas à  nil toute seule donc boum)
  • Philippe49Philippe49 Membre
    novembre 2008 modifié #9
    dans 1227444218:

    Heu avec alloc/initWithArray et non arrayWithArray, non ?


    oui, auquel cas cela marche directement, comme le suggérait Schlum


    [size=12pt]Code essai[/size]
    #import <Foundation/Foundation.h>

    @interface Constants : NSObject {
    }
    @end

    @implementation Constants
    +(NSArray *) sharedArray {
    static NSArray * array=nil;
    if(nil==array) {
    array=[[NSArray alloc] initWithObjects:@toto,@titi,nil];
    }
    return array;
    }
    @end

    int main(int argc, char *argv[]) {

    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
    NSLog(@%@",[Constants sharedArray]);
    NSLog(@%@",[Constants sharedArray]);
    [pool drain];
    return 0;
    }

    [size=12pt]Exécution[/size]
    % gcc pgm.m -o pgm -framework Foundation
    % pgm
    2008-11-23 14:29:28.015 pgm[981:10b] (
        toto,
        titi
    )
    2008-11-23 14:29:28.017 pgm[981:10b] (
        toto,
        titi
    )

  • schlumschlum Membre
    09:00 modifié #10
    dans 1227434651:

    Oui, mais logiquement il devrait alors être créé à  chaque appel de la méthode kFilterDistance... non?

    Dans le cas contraire, quelle serait la meilleure manière de créer un tableau en tant que constante?



    Non, parce qu'il ne se remet pas à  nil[/b] tout seul !
Connectez-vous ou Inscrivez-vous pour répondre.