【问题标题】:Inheriting accessors in Objective-C在 Objective-C 中继承访问器
【发布时间】:2012-04-13 15:39:56
【问题描述】:

这是我的第一篇文章;这个网站是一个非常宝贵的资源。

我对 Objective-c 还很陌生,所以请多多包涵。

所以我有一个基类,其中包含一些我想要“私有”的属性,所以我将它们设为只读。需要明确的是,我不希望它们在外部是可变的,但我确实不想在这个类中使用“set”访问器。所以...

// .h file
@interface Vehicle
@property (nonatomic, readonly) int speed;
@end

我还在类别接口块中重复了属性声明,以使访问器在此类中可写

// .m file
//Private properties and methods
@interface Vehicle()
@property (nonatomic, readwrite) int speed;
@end

@implementation
@synthesize speed = _speed;
- (void) someMethod {
    [self setSpeed:10]; // Works fine
}

@end

但是现在如果我继承这个类,派生类就不再有 set 访问器方法(在我的例子中是 setSpeed)。需要重新合成吗?似乎那样会破坏继承的目的。我知道我可以直接修改实例变量(_speed = 10;)但宁愿不这样做。我确定我的理解有问题。谢谢!

// Example
@interface Ship : Vehicle
@end

@implementation
- (void) someOtherMethod {
    [self setSpeed: 2]; // DOES NOT WORK, would like it to
}
@end

【问题讨论】:

  • 我想我要问的是如何继承私有@interface someName() 类别..
  • 我猜您可以通过仅用于派生类包含的标头共享私有接口。 (我自己没有尝试过,因此评论而不是答案。)

标签: objective-c inheritance readonly setter accessor


【解决方案1】:

但是现在如果我继承这个类,派生类就不再有 set 访问器方法(在我的例子中是 setSpeed)。

其实它确实有 set 访问器,只是编译器不知道而已。你有一个选择:

  • 将类扩展名(@interface Vehicle() .... @end 位放在一个单独的头文件中,该文件将导入到 Vehicle 及其子类(或使用类别)的 .m 中
  • 在子类的类扩展中重新声明读/写属性。为避免出现警告,请在子类的实现中使用 @dynamic speed。

【讨论】:

  • 啊,谢谢,我隐约记得在某个时候读过关于@dynamic 的内容。这听起来是对的,因为你和马塞洛在同一条轨道上。多个解决方案的额外 ++ 点。当我回到我的 mac 并标记为正确时,我会尝试它。有什么办法可以通过协议做到这一点?重新声明似乎很乏味,但我可以忍受。再次感谢。
  • 更新:上面测试过,效果很好。我意识到这两种解决方案实际上是相同的,额外的头文件只是节省了复制/粘贴该块的时间。还注意到,如果我使用合成而不是动态,它不会发出警告,功能也不会改变。
  • @Patrick:如果您使用@synthesize,它将生成新的访问器,并且可能会为子类生成新的ivar,因此请使用@dynamic。
  • 谢谢,我没有区分。这就是我想要的,子类中的新 ivars。不访问基类变量。考虑到子类的数量,#import 解决方案似乎效果最好。一般来说,我希望有一种简单的方法来继承仅在 .m 实现文件中的方法。
【解决方案2】:

由于没有“受保护”方法之类的东西,因此您需要在匿名类别所在的位置创建一个私有共享标头。然后,您的原始实现和派生类都包含此标头以访问此“私有”内容。

【讨论】:

  • 说得好,我想这种方法中的头文件没有命名约定。我正在使用 BaseClassNamePrivate,但这很简单。
猜你喜欢
  • 1970-01-01
  • 2012-01-05
  • 2012-03-10
  • 2013-09-26
  • 1970-01-01
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
相关资源
最近更新 更多