2009-09-21 6 views
0

J'ai regardé sur le web mais je ne trouve rien qui puisse aider. Ma question est: est-ce que je peux écrire le tableau de pneus [x] en tant que NSArray, si oui, quelle serait la syntaxe pour déclarer et allouer les objets d'instance de classe de pneu?Puis-je configurer le tableau de pneus ci-dessous en tant que NSArray?

@interface CarClass : NSObject { 
    EngineClass *engine; 
    TireClass *tires[4];   
} 

.

@implementation CarClass 
- (id) init { 
    [super init]; 
    NSLog(@"_init: %@", NSStringFromClass([self class])); 
    engine= [[EngineClass alloc] init]; 
    tires[0]= [[TireClass alloc] init]; 
    tires[1]= [[TireClass alloc] init]; 
    tires[2]= [[TireClass alloc] init]; 
    tires[3]= [[TireClass alloc] init]; 
    return self; 
} 

EDIT:

ceci est ma méthode dealloc pour la CarClass

- (void) dealloc { 
    NSLog(@"_deal: %@", NSStringFromClass([self class])); 
    [engine release]; 
    [tires release]; 
    [super dealloc]; 
} 

Encore un peu confus au sujet de la retenir dans le NSArray ci-dessous, si j'ajoute un supplément de [pneus retain] à le CarClass: init, les pneus ne sont pas libérés. Cependant, comme le code est maintenant les pneus libèrent avec ou sans fin retenir (ie)

tires = [[NSArray arrayWithObjects: 
       [[[TireClass alloc] init] autorelease], 
       [[[TireClass alloc] init] autorelease], 
       [[[TireClass alloc] init] autorelease], 
       [[[TireClass alloc] init] autorelease], 
       nil] retain]; 

tires = [NSArray arrayWithObjects: 
       [[[TireClass alloc] init] autorelease], 
       [[[TireClass alloc] init] autorelease], 
       [[[TireClass alloc] init] autorelease], 
       [[[TireClass alloc] init] autorelease], 
       nil]; 

FINAL EDIT: Je pensais aussi que sans autorelease sur les pneus individuels libérant enfin le NSArray dans le dealloc libérerait à la fois le tableau et les objets vers lesquels il pointe, cela ne semble pas être le cas.

acclamations -Gary-

Répondre

4
@interface CarClass : NSObject { 
    EngineClass *engine; 
    NSArray *tires; 
} 

.

@implementation CarClass 
- (id) init { 
    self = [super init]; 
    if (self == nil) 
     return nil; 
    NSLog(@"_init: %@", NSStringFromClass([self class])); 
    engine= [[EngineClass alloc] init]; 
    tires = [[NSArray arrayWithObjects: 
     [[[TireClass alloc] init] autorelease], 
     [[[TireClass alloc] init] autorelease], 
     [[[TireClass alloc] init] autorelease], 
     [[[TireClass alloc] init] autorelease], 
     nil] retain]; 
    return self; 
} 
+0

Ai-je eu ce droit, vous n'alloc le tableau, mais plutôt les objets qu'il contient? Désolé juste d'essayer de comprendre. – fuzzygoat

+0

Le code appelle la méthode '+ [NSArray arrayWithObjects:]', qui est une méthode pratique qui alloue automatiquement, puis libère automatiquement l'objet tableau (d'où l'appel à 'retain'). – mipadi

+0

@mipadi pouvez-vous expliquer le bit de retenue, ai-je raison de penser que le code retient le NSArray, les objets sont ensuite auto-libérés. Juste ne sais pas ce qui se passe à la NSArray et pourquoi il est conservé? – fuzzygoat

0

Vous n'avez pas toujours besoin d'utiliser un tableau NSArray pour les collections. Que diriez-vous de cette façon qui a un peu plus d'informations sur chaque pneu:

@interface CarClass : NSObject { 
    EngineClass *engine; 
    NSDictionary *tiresDictionary; 
} 

@implementation CarClass 
- (id) init { 
    self = [super init]; 
    if (!self) { 
     return nil; 
    } 
    NSLog(@"_init: %@", NSStringFromClass([self class])); 
    engine= [[EngineClass alloc] init]; 
    tiresDictionary = [[NSDictionary dictionaryWithObjectsAndKeys: 
    [[[TireClass alloc] init] autorelease], @"LeftFrontTyre", 
    [[[TireClass alloc] init] autorelease], @"RightFrontTyre", 
    [[[TireClass alloc] init] autorelease], @"LeftRearTyre", 
    [[[TireClass alloc] init] autorelease], @"RightRearTyre", 
    nil] retain]; 
    return self; 
} 

De cette façon, vous avez encore une classe de collection, mais plutôt que d'essayer de se souvenir que l'index d'un tableau fait référence à quel pneu, vous avez un dictionnaire avec des clés descriptives afin que vous puissiez vous référer à chaque pneu par un nom.

+0

devrait "pneus = [[NSDictionary" être "pneusDictionary = [[NSDictionary", pas un expert de loin, mais semble qu'il devrait être. – fuzzygoat

+0

Oui. Fixé. Montre pourquoi copier et coller est sujet aux erreurs! – Abizern

+0

Si vous mettez tout cela dans un dictionnaire ... pourquoi ne pas avoir des variables d'instance séparées comme 'TireClass * leftFrontTire',' TireClass * rightFrontTire', etc.? – mipadi

0

Je voudrais changer un peu l'exemple de Nikolai. Puisque je ne veux pas ajouter autorelease et conserver où aucun n'est nécessaire, moins de code est toujours moins de code sujettes aux bugs.

@interface CarClass : NSObject { 
    EngineClass *engine; 
    NSArray *tires; 
} 

@implementation CarClass 
- (id) init { 
    self = [super init]; 
    if (self) { 
    NSLog(@"_init: %@", NSStringFromClass([self class])); 
    engine= [[EngineClass alloc] init]; 
    tires = [[NSArray alloc] initWithObjects: 
     [TireClass new], [TireClass new], [TireClass new], [TireClass new], nil]; 
    [tires makeObjectsPerormSelector:@selector(release)]; 
    } 
    return self; 
} 

Le [tires makeObjectsPerormSelector:@selector(release)]; peut être effrayant, mais est utile et très performant. Un moyen un peu moins performant, mais peut-être plus clair serait de laisser le TireClass implémenter une méthode d'usine, et de créer des objets autoreleased de celui-là. Comme si:

+(TireClass)tire; 
{ 
    return [[self new] autorelease]; 
} 

s'il vous plaît arrêter également nommer vos classes de classe « Quelque chose », un chaton meurt si vous :)

+0

Je vous remercie, je vais laisser tomber le nom de la classe, son plus pour aider l'apprentissage d'un choix de style conscient à ce stade. Merci beaucoup pour vos pensées. – fuzzygoat

Questions connexes