这是一个相当复杂的继承层次结构,所以忍受我(我试图简化事情,而不是陈述我使用的确切情况,这更复杂): -
假设我创建了一个UITextField
的子类TextField
,这是我自己的自定义增强型通用文本字段。现在,为了提供此增强功能,我在init
的{{1}}方法中设置TextField
,以便将super.delegate = self
中的所有委托方法发送到{{1} }}。 UITextField
实现TextField
协议,并接收这些委托方法来做一些有趣的事情。
但是,反过来,我想让TextField
拥有拥有委托。所以我创建了一个名为UITextFieldDelegate
的新协议(注意缺少TextField
- 前缀!)并给TextFieldDelegate
一个带有相应属性的ivar UI
,以便其他类可以接收委托来自TextField
的方法。
我希望你还和我在一起,因为到目前为止我还没有做过任何太复杂的事情。但是让我们说现在,我创建另一个id<TextFieldDelegate> __weak delegate
的自定义子类,让我们称之为TextField
(在现实生活中,人们可能不需要创建一个子类来实现密码功能,但是让我们假设有一些相当复杂的实现需要这个。)
我们还假设我想要使TextField
(类似PasswordTextField
具有委托属性)能够发送一组增强的委托方法。例如,也许它可以发送方法PasswordTextField
,一旦密码达到所需的复杂程度,就会发送该方法。现在,由于常规TextField
中找不到此行为,我创建了一个新协议:passwordIsSecure
,它为TextField
和定义新的委托方法继承PasswordTextFieldDelegate <TextFieldDelegate>
发送的所有委托方法。
问题是:如何在PasswordTextField
中实现此功能?不起作用的事情:
继承
我不能简单地从TextField
继承委托,因为PasswordTextField
的委托只符合TextField
而不是TextField
,因此我无法发送TextFieldDelegate
之类的方法{1}}因为PasswordTextFieldDelegate
没有这样的方法。
覆盖ivar
我可以尝试在名为[delegate passwordIsSecure]
的委托中声明一个ivar,但编译器抱怨这是一个重复的声明,因为当然在超类中已经有一个名为delegate的ivar,所以这也不起作用*
修改超类
我可以回到TextFieldDelegate
类并重新定义代理以实现PasswordTextField
和 TextField
,但这看起来很混乱,并告诉{{1它可以发送TextFieldDelegate
方法,当然,它不能!
我没有尝试过这个,只是因为它似乎打破了书中所有合理的编码规则。
总之,必须有一些方法可以做到这一点,这样一个类的子类可以拥有它自己的委托,它是超类委托的子委托,并且所有这些都可以很好地融合在一起,但我只能'搞清楚!有什么想法吗?
(*作为一个副作用,我不明白为什么编译器会在PasswordTextFieldDelegate
声明一个名为“委托”的“重复”ivar时抱怨,但是当TextField
声明一个名为delegate的ivar时不会抱怨这可能是PasswordTextFieldDelegate
属性的副本,称为委托!)
答案 0 :(得分:1)
UITextField委托ivar名为_delegate,而不是委托。因此,为什么你在TextField中再次声明它,而不是在PasswordTextField中。
至于你的委托继承问题。我不确定ObjectiveC是否支持你想要的东西。
您可能只需要输入您的委托'id',而不是'id&lt; TextFieldDelegate&gt;'。然后你可以覆盖setDelegate并确保委托传递conformsToProtocol。但是,您将丢失此处的编译时检查,并且仅对conformsToProtocol
进行运行时检查答案 1 :(得分:1)
所以,那里!工作..并设法有编译时警告..
SimpleParent.h
@protocol Parentprotocol <NSObject>
@end
@interface SimpleParent : NSObject {
id<Parentprotocol> obj;
}
@property (retain) id<Parentprotocol> obj;
@end
SimpleParent.m
#import "SimpleParent.h"
@implementation SimpleParent
@synthesize obj;
@end
SimpleChild.h
#import <Foundation/Foundation.h>
#import "SimpleParent.h"
@protocol SimpleChildProtocol <Parentprotocol>
@end
@interface SimpleChild : NSObject
@property (assign) id<SimpleChildProtocol> obj;
@end
SimpleChild.m
#import "SimpleChild.h"
@implementation SimpleChild
@synthesize obj;
@end
答案 2 :(得分:1)
这是一个相当令人困惑的问题,所以请原谅我,如果我错过了这一点,但看起来你的三个不同的继承级别每个都有不同的委托要求,每个代表都必须遵循不同的协议,那么将每个级别的委托作为一个不同名称的ivar,并作为一个不同的参考,它会是一个解决方案吗?
例如,您的基类将具有其delegate
,您已决定将其分配给第一个继承子类。这有自己的委托,名为level1delegate
,而下一个级别有另一个委托,名为level2delegate
。如果该对象符合所有三个协议,您当然可以将所有这三个设置为同一个对象。
基本上,没有规则说委托必须被称为“委托”,所以不要因为不打破它而撕裂自己。