代码之家  ›  专栏  ›  技术社区  ›  William Jockusch

目标C-子类中的窄实例变量类型?

  •  4
  • William Jockusch  · 技术社区  · 14 年前

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

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

    我刚刚试过那个代码,Xcode给了我一个编译错误。我想知道有没有办法。

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

    4 回复  |  直到 14 年前
        1
  •  1
  •   Alex Wayne    14 年前

    不,你根本不能重新申报艾瓦尔。但是,您可以创建一个新的基于方法的属性,而无需创建新的ivar。

    @property (nonatomic, copy) NSMutableArray* mutableFriends;
    
    @implementation MutablePerson
    
    - (NSMutableArray*)mutableFriends {
      return (NSMutableArray*)friendArray;
    }
    
    - (void)setMutableFriends:(NSMutableArray*)friends {
      self.friendsArray = [friends mutableCopy];
    }
    
    @end
    
        2
  •  0
  •   Eiko    14 年前

    @上课一点意义都没有。。。应该是@interface。所以第一个错误是纯粹的语法错误。

    不,你不能改变ivar的类型。这有一个很好的原因:缩小范围(就像你做的那样)是行不通的,因为父类可能依赖于不同的实现。扩大它不能起到同样的作用(主要是因为类似的原因)。

        3
  •  0
  •   Benedict Cohen    14 年前

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

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

    MutablePerson 您可以声明另一个数组来存储 friends 或者你可以直接通过 addFriend: :

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

    直接访问ivar并不明智。我会重新考虑你的班级设计。有一个易变和不变的人的版本的理由是什么?

        4
  •  0
  •   William Jockusch    14 年前

    我结束了重写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];
    }