是否可以缩小子类中ivar的允许类型。像这样:
@interface person: NSObject {
NSArray *friendArray;
}
@interface mutablePerson: person {
NSMutableArray *friendArray;
}
我刚尝试了那个确切的代码,Xcode给了我一个编译错误。我想知道是否有办法绕过它。
我正在研究的项目将会出现很多这种情况。我知道我可以使用强制转换来使代码工作。但如果我这样做,我会做很多演员表,我想知道是否有更好的方法。
答案 0 :(得分:1)
不,你根本不能重新声明伊娃。但是,您可以创建基于新方法的属性,而无需创建新的ivar。
@property (nonatomic, copy) NSMutableArray* mutableFriends;
@implementation MutablePerson
- (NSMutableArray*)mutableFriends {
return (NSMutableArray*)friendArray;
}
- (void)setMutableFriends:(NSMutableArray*)friends {
self.friendsArray = [friends mutableCopy];
}
@end
答案 1 :(得分:0)
@class根本没有意义......它应该是@interface。所以第一个错误纯粹是语法上的。
不,你不能改变伊娃的类型。这有一个很好的理由:缩小它(就像你一样)是行不通的,因为父类可能依赖于不同的实现。扩大它不能很好地工作(主要是出于类似的原因。
答案 2 :(得分:0)
如果编译器说'不'那么这就是你的答案。我会使用访问者:
//Person
-(NSArray *)friends;
//MutablePerson
-(void)addFriend:(person *)friend;
在MutablePerson
中,您可以声明另一个数组来存储friends
,或者您可以直接在addFriend:
中访问ivar:
-(void)addFriend:(person *)friend
{
_friendsArray = [_friendsArray arrayByAddingObject: friend];
}
直接访问ivars并不聪明。我会重新考虑你的课堂设计。拥有可变和不可变版本的人的理由是什么?
答案 3 :(得分: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];
}