如何使用更具体的类型覆盖超类的属性?

26

场景
我有一个情况,在一���名为AbstractRequest的基类中,有一个在头文件中声明的委托属性,其类型为id <AbstractRequestDelegate>

@property (nonatomic, assign) id <AbstractRequestDelegate> delegate;
抽象委托协议包含几个必需的方法,而且正如“抽象”一词所示,AbstractRequestAbstractRequestDelegate都是旨在进行子类化/扩展。例如,ConcreteRequest子类和扩展协议ConcreteRequestDelegates,两者都添加了额外的方法以补充抽象方法。其意图是,抽象类和具体类的方法都可以向单个分配的委托实例发送消息。
在某个时刻,ConcreteRequest想要调用由ConcreteRequestDelegate定义的委托方法。由于委托的类型是id,编译器会发出警告,说明可能未实现此方法。
ConcreteRequest.m:38: warning: property 'delegate' requires method '-delegate' to be defined - use @synthesize, @dynamic or provide a method implementation 问题 这个警告是合理的,因为该属性的类型是id <AbstractRequestDelegate>。为了解决这个问题,我想让编译器明确指出分配给ConcreteRequest实例的委托必须是id <ConcreteRequestDelegate>类型的。这对我来说听起来非常合理,所以我在ConcreteRequest头文件中添加了一个新的属性,希望覆盖抽象属性。
@property (nonatomic, assign) id <ConcreteRequestDelegate> delegate;

但是这就是编译器和我不同意的地方,可能有充分的理由。我本以为它会警告我用错误类型重写超类的属性,但实际上它只要求我重新合成这个新属性。我不想这样做,因为超类的方法将无法访问相同的委托属性。

问题
是否有一种方法在具体子类中“重新声明”该属性,并添加类型信息?或者您能否发现我的思维错误,因为这可能是一个常见的问题,直到现在我才没有遇到?

感谢您的帮助,
EP.

注:本作品中出现的所有类和协议名称均为虚构。任何与真实类和协议名称(开源或专利)的相似之处纯属巧合。


2
哈哈,关于 P.S. :D... 你能否发布所有接口和类的代码?你的解释太长了。 - Inder Kumar Rathore
这已经让我花了半个小时了,也许其他人可以看出这些冗长的词语。如果一切都失败了,我将投入时间来伪代码化这些类。 - epologee
为什么你认为重新合成会造成问题? - Inder Kumar Rathore
2个回答

11

这个警告已经给出了正确的线索。我在覆盖子类中使用了 @dynamic,一切都很好。


1
你能否详细说明一下你在子类中做了什么才使它正常工作?此外,你还认为这是一个好的模式吗? - shaunlim
3
对于以后看到这篇回答的任何人,这篇回答的意思是,如果你在子类中简单地重新声明属性,它实际上是起作用的,但会有一个警告。然后,如果你进入你的.m文件中的实现部分,并添加"@dynamic samevariablename"这一行,它就有效地消除了@property声明上的警告/问题。可能并不期望它会这样做,因为警告在问题得到解决的位置上不同,但实际上确实如此。这对我也起作用了。 - John Bushnell

2

只需要在 ConcreteRequest.m 中合成 id<ConcreteRequestDelegate>delegate,它将正常工作...不会产生任何问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接