4

是否可以缩小子类中允许的 ivar 类型。像这样的东西:

@interface person: NSObject {
  NSArray *friendArray;
}

@interface mutablePerson: person {
  NSMutableArray *friendArray;
}

我刚刚尝试了那个确切的代码,Xcode 给了我一个编译错误。我想知道是否有办法解决它。

我正在从事的项目将有很多这种情况。我知道我可以使用强制转换来使代码正常工作。但是如果我这样做的话,我会做很多演员,我想知道是否有更好的方法。

4

4 回答 4

1

不,你根本不能重新声明 ivars。但是,您可以在不创建新 ivar 的情况下创建基于新方法的属性。

@property (nonatomic, copy) NSMutableArray* mutableFriends;

@implementation MutablePerson

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

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

@end
于 2010-11-22T17:20:47.623 回答
0

@class 根本没有意义......它应该是@interface。所以第一个错误纯粹是语法错误。

不,您不能更改 ivar 的类型。这是有充分理由的:缩小范围(如您所做的那样)是行不通的,因为父类可能依赖于不同的实现。扩大它也不能奏效(主要是出于类似的原因。

于 2010-11-22T17:20:07.897 回答
0

如果编译器说“不”,那么这就是你的答案。我会使用访问器:

//Person
-(NSArray *)friends;


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

MutablePerson您可以声明另一个要存储的数组,friends或者您可以直接访问 ivar addFriend:

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

直接访问 ivars 并不聪明。我会重新考虑你的班级设计。拥有可变和不可变版本的人的理由是什么?

于 2010-11-22T17:20:44.537 回答
0

我结束了覆盖 setter 以断言正在设置的对象是适当的类型,并创建了一个新的只读 getter,如下所示:

@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];
}
于 2010-11-24T22:16:00.283 回答