2010-11-22 3 views
4

Est-il possible d'affiner le type autorisé d'un ivar dans une sous-classe. Quelque chose comme ceci:Objectif C - types de variables d'instances étroites dans les sous-classes?

@interface person: NSObject { 
    NSArray *friendArray; 
} 

@interface mutablePerson: person { 
    NSMutableArray *friendArray; 
} 

J'ai juste essayé ce code exact, et Xcode m'a donné une erreur de compilation. Je me demande s'il y a un moyen de contourner cela.

Le projet sur lequel je travaille va avoir beaucoup de ce genre de situation. Je comprends que je peux utiliser des conversions pour faire fonctionner le code. Mais je ferai énormément de moulages si je fais cela, et je me demande s'il y a un meilleur moyen.

+1

1) Rétrécissement n'est pas autorisé , mais vous l'avez élargi, ce qui est. 2) Vous déclarez le même nom de membre - vous ne pouvez pas le faire. donnez-lui un nouveau nom et changez les accesseurs. –

+0

avez-vous essayé/implémenté le protocole NSMutableCopying? c'est probablement ce que vous voulez. – nacho4d

+0

@Alex Brown. Il s'est rétréci. 'NSMutableArray' est une sous-classe de' NSArray'. –

Répondre

0

j'ai fini redéfinissant la setter d'affirmer que l'objet est fixé du type approprié, et la création d'une nouvelle lecture seule getter, comme ceci:

@interface MutablePerson { 
} 

@property (readonly) NSMutableArray *mutableFriendArray; 

@implementation MutablePerson 

-(NSMutableArray *) mutableFriendArray { 
    NSMutableArray *ret = (NSMutableArray *)[super friendArray]; 
    NSAssert ([ret isKindOfClass: [NSMutableArray class]], @"array should be mutable"); 
    return ret; 
} 

-(void) setFriendArray: (NSMutableArray *) array { 
    NSAssert ([array isKindOfClass: [NSMutableArray class]], @"array should be mutable"); 
    [super setFriendArray: array]; 
} 
0

@class n'a pas de sens du tout ... il devrait être @interface. Donc, la première erreur est purement syntaxique.

Et non, vous ne pouvez pas changer le type d'un ivar. Et c'est pour une bonne raison: le rétrécir (comme vous le faites) ne peut pas fonctionner, car la classe parente peut s'appuyer sur une implémentation différente. . L'élargissement ne peut pas fonctionner aussi bien (surtout pour la raison analogue

+0

Merci, corrigé le code ici; c'était correct quand je l'ai essayé dans Xcode. –

0

Si le compilateur dit « non », c'est votre réponse que je voudrais utiliser accesseurs.

//Person 
-(NSArray *)friends; 


//MutablePerson 
-(void)addFriend:(person *)friend; 

Dans le MutablePerson, vous pouvez déclarer une autre tableau pour stocker friends ou vous pouvez accéder au Ivar directement addFriend::..

-(void)addFriend:(person *)friend 
{ 
    _friendsArray = [_friendsArray arrayByAddingObject: friend]; 
}  

Je réexaminerait l'accès Ivars n'est pas directement intelligent design de votre classe Quelle est la raison d'être d'avoir un mutable et versions immuables de la personne?

1

Non, vous ne pouvez pas redéclarer des ivars du tout. Cependant, vous pouvez créer une nouvelle propriété basée sur une méthode sans faire de nouvelle ivar.

@property (nonatomic, copy) NSMutableArray* mutableFriends; 

@implementation MutablePerson 

- (NSMutableArray*)mutableFriends { 
    return (NSMutableArray*)friendArray; 
} 

- (void)setMutableFriends:(NSMutableArray*)friends { 
    self.friendsArray = [friends mutableCopy]; 
} 

@end 
Questions connexes