Objective C narrow instance variable types in subclasses?

Is it possible to narrow down a valid ivar type in a subclass. Something like that:

@interface person: NSObject { NSArray *friendArray; } @interface mutablePerson: person { NSMutableArray *friendArray; } 

I just tried this exact code, and Xcode gave me a compilation error. I am wondering if there is a way around this.

The project I'm working on will have this situation. I understand that I can use casts to make the code work. But if I do this, I will make a lot of prizes, and I wonder if there is a better way.

+4
source share
4 answers

I ended up redefining the setter to claim that the given object is of the appropriate type and creates a new readable getter, for example:

 @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
source

No, you cannot redraw the Ivars at all. However, you can create a new property based on a method without creating a new ivar.

 @property (nonatomic, copy) NSMutableArray* mutableFriends; @implementation MutablePerson - (NSMutableArray*)mutableFriends { return (NSMutableArray*)friendArray; } - (void)setMutableFriends:(NSMutableArray*)friends { self.friendsArray = [friends mutableCopy]; } @end 
+1
source

@class doesn't make sense at all ... it should be @interface. Thus, the first error is purely syntactic.

And no, you cannot change the type of ivar. And this is for a good reason: narrowing it down (like yours) cannot work, because the parent class can rely on another implementation. The extension may not work (mainly for a similar reason.

0
source

If the compiler says no, then your answer. I would use accessors:

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

In MutablePerson you can declare another array to store friends or you can access ivar directly in addFriend: ::

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

Access to ivars directly is not reasonable. I would review your class. What is the rationale for the presence of variable and unchanging versions of man?

0
source

All Articles