2011-05-05 87 views
26

场景
我有一个情况称为AbstractRequest基类具有在头文件中声明id <AbstractRequestDelegate>类型的代表属性:如何用更具体的类型覆盖超类的属性?

@property (nonatomic, assign) id <AbstractRequestDelegate> delegate; 

抽象代表协议包含一些必要方法,并且如用“抽象”一词表示,AbstractRequestAbstractRequestDelegate都打算是子类/扩展。

其中一个例子是ConcreteRequest和扩展协议ConcreteRequestDelegates的子类,它们都向抽象的方法添加额外的方法。目的是抽象类和具体类方法都可以将消息发送给单个分配的委托实例。

在某个时间点ConcreteRequest想调用由ConcreteRequestDelegate定义的委托上的方法。由于委托的类型是id,编译器会发出警告,说明此方法可能不会实现。

ConcreteRequest.m:38:警告: 属性 '委托' 需要定义方法 '-delegate' - 使用 @synthesize,@dynamic或提供 方法实现

问题
此警告是有道理的,因为该属性毕竟输入到id <AbstractRequestDelegate>。为了解决这个问题,我想向编译器说明分配给具体实例的委托必须是id <ConcreteRequestDelegate>。这听起来非常合理的我,所以我把在ConcreteRequest头一个新的属性,希望重写抽象的:

@property (nonatomic, assign) id <ConcreteRequestDelegate> delegate; 

但是,这是编译器感到不舒服,可能有很好的理由。我原以为它会给出超越类型错误的超级财产的警告,但它只是要求我重新合成这个新财产。我不想去那里,因为那么超类的方法将不能访问相同的委托属性。

问题
有没有一种方式,以“重新申报”与添加的类型信息的具体子类的属性?或者你能否在我的想法中发现错误,也许这是一个相当普遍的问题,我直到现在才发现?

干杯,
EP。

P.S.本文中出现的所有类别和协议名称都是虚构的。与真实的类和协议名称,开源或专利的任何相似之处纯属巧合。

+2

lol on P.S. :D ...你可以发布所有界面和类的代码吗......你的解释太长了 – 2011-05-05 10:28:09

+0

这已经花了我半个小时,也许别人可以看穿很多单词。如果全部失败,我会投入时间对这些类进行伪代码。 – epologee 2011-05-05 10:33:02

+0

:D为什么你重新合成会产生问题 – 2011-05-05 10:36:38

回答

11

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

+1

你能否详细说明你在子类中做了什么来实现它的工作?另外,你是否仍然相信这是一个很好的模式? – shaunlim 2014-08-22 07:11:21

+3

对于后来遇到这个问题的人来说,这个答案的意思是,如果你只是重新声明子类中的属性,它有效地起作用,但是有警告。如果您然后进入.m文件中的实现部分并添加“@dynamic samevariablename”行,它会使@property声明的警告/问题消失。可能并不指望它会这样做,因为警告与问题解决的地点不同,但它确实存在。它也适用于我。 – 2015-05-15 06:53:04

2

只是综合id<ConcreteRequestDelegate>delegateConcreteRequest.m它会正常工作......它不会产生任何问题。