【问题标题】:Objective C -- narrow instance variable types in subclasses?Objective C - 在子类中缩小实例变量类型?
【发布时间】:2010-11-22 17:06:59
【问题描述】:

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

@interface person: NSObject {
  NSArray *friendArray;
}

@interface mutablePerson: person {
  NSMutableArray *friendArray;
}

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

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

【问题讨论】:

  • 1) 收窄是不允许的,但你已经加宽了,就是这样。 2)您再次声明相同的成员名称 - 您不能这样做。给它一个新名称并更改访问器。
  • 你尝试过/实现过 NSMutableCopying 协议吗?可能就是你想要的。
  • @Alex Brown。它已经变窄了。 NSMutableArray 是 NSArray 的子类。
  • 加宽了。 NSMutableArray 至少和 NSArray 一样强大。有人抓住一个 NSMutableArray 并认为它是一个 NSArray 不会有任何奇怪的影响,因此你的类的 API 和它的新子类没有改变。

标签: iphone ios subclassing


【解决方案1】:

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

@property (nonatomic, copy) NSMutableArray* mutableFriends;

@implementation MutablePerson

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

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

@end

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 谢谢,这里修复了代码;当我在 Xcode 中尝试时它是正确的。
    【解决方案3】:

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

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

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

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2011-10-07
        • 2011-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多