Objective C — narrow instance variable types in subclasses?

微笑、不失礼 提交于 2019-12-17 20:25:22

问题


Is it possible to narrow the allowed type of an ivar in a subclass. Something like this:

@interface person: NSObject {
  NSArray *friendArray;
}

@interface mutablePerson: person {
  NSMutableArray *friendArray;
}

I just tried that exact code, and Xcode gave me a compile error. I'm wondering if there is a way around it.

The project I am working on is going to have a lot of this sort of situation. I understand that I can use casts to make the code work. But I will be making an awful lot of casts if I do that, and I'm wondering if there is a better way.


回答1:


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



回答2:


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




回答3:


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?




回答4:


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];
}


来源:https://stackoverflow.com/questions/4248066/objective-c-narrow-instance-variable-types-in-subclasses

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!