Is it possible to narrow the allowed type of an ivar in a subclass. Something like this:
@interface person: NSObject {
NSArray *friendArray;
}
@interface
No, you can't redeclare ivars at all. However, you can make a new method based property without making a new ivar.
@property (nonatomic, copy) NSMutableArray* mutableFriends;
@implementation MutablePerson
- (NSMutableArray*)mutableFriends {
return (NSMutableArray*)friendArray;
}
- (void)setMutableFriends:(NSMutableArray*)friends {
self.friendsArray = [friends mutableCopy];
}
@end
I ended overriding the setter to assert that the object being set is of the appropriate type, and creating a new read-only getter, like this:
@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];
}
If the compiler says 'no' then that's your answer. I would use accessors:
//Person
-(NSArray *)friends;
//MutablePerson
-(void)addFriend:(person *)friend;
In the MutablePerson
you could declare another array to store friends
or you could access the ivar directly in addFriend:
:
-(void)addFriend:(person *)friend
{
_friendsArray = [_friendsArray arrayByAddingObject: friend];
}
Accessing ivars directly isn't smart. I would reconsider your class design. What's the rationale for having a mutable and immutable versions of person?
@class doesn't make sense at all... it should be @interface. So the first error is purely syntactical.
And no, you cannot change the type of an ivar. And that's for a good reason: Narrowing it down (as you do) can't work, because the parent class might rely on a different implementation. Widening it can't work as well (mainly for the analogous reason.