[英]Objective-C — Subclass of delegate in subclass
这是一个相当复杂的继承层次结构,所以忍受我(我试图简化事情,而不是陈述我使用的确切情况,这更复杂): -
假设我创建了一个名为TextField
的UITextField
子类,它是我自己的自定义增强通用文本字段。 现在,为了提供这种增强功能,在TextField
的init
方法中,我设置了super.delegate = self
以便将UITextField
中的所有委托方法发送到TextField
。 TextField
实现UITextFieldDelegate
协议并接收这些委托方法以执行一些有趣的操作。
但是,反过来,我想让它成为TextField
拥有它自己的委托。 所以我创建了一个名为TextFieldDelegate
的新协议(注意缺少UI
-prefix!),并为TextField
一个具有相应属性的ivar id<TextFieldDelegate> __weak delegate
,以便其他类可以从TextField
接收委托方法。
我希望你还和我在一起,因为到目前为止我还没有做过任何太复杂的事情。 但是让我们说现在,我创建另一个TextField
自定义子类,让我们称之为PasswordTextField
(在现实生活中,人们可能不需要创建一个子类来实现密码功能,但让我们假设有一些相当复杂的实现这需要这个)。
让我们假设我想让它成为PasswordTextField
(类似TextField
具有委托属性)能够发送一组增强的委托方法。 例如,也许它可以发送一个方法passwordIsSecure
,一旦密码达到所需的复杂程度就会发送该方法。 现在,由于在常规TextField
找不到这种行为,我创建了一个新协议: PasswordTextFieldDelegate <TextFieldDelegate>
,它定义了PasswordTextField
的新委托方法, 并继承了TextField
发送的所有委托方法。
问题是:我如何在PasswordTextField
实现它? 不起作用的事情:
遗产
我不能简单地从TextField
继承委托,因为TextField
的委托只符合TextFieldDelegate
而不是PasswordTextFieldDelegate
,所以我不能发送像[delegate passwordIsSecure]
这样的方法,因为TextFieldDelegate
没有这样的方法。
压倒伊娃
我可以尝试在PasswordTextField
声明一个名为delegate的ivar,但编译器抱怨这是一个重复的声明,因为当然在超类中已经有一个名为delegate的ivar,所以这也不起作用*。
修改超类
我可以回到TextField
类并重新定义委托以实现TextFieldDelegate
和 PasswordTextFieldDelegate
,但这看起来很乱并且告诉TextField
它可以发送PasswordTextFieldDelegate
方法,当然,它不能!
我没有试过这个,只是因为它似乎打破了书中所有合理的编码规则。
总而言之,必须有一些方法来做到这一点,这样一个类的子类可以拥有它自己的委托,它是超类委托的子委托,并且所有这些都可以很好地融合在一起,但我无法理解它出来了! 有任何想法吗?
(*作为一个副作用,我不明白为什么编译器会在PasswordTextField
声明一个名为delegate的“重复”ivar时抱怨,但是当TextField
声明一个名为delegate的ivar时,它不会抱怨,这可能是UITextField
属性的副本代表!)
UITextField委托ivar名为_delegate,而不是委托。 因此,为什么你在TextField中再次声明它,但在PasswordTextField中却没有。
至于你的委托继承问题。 我不确定ObjectiveC是否支持你想要的东西。
您可能只需要键入您的委托'id',而不是'id <TextFieldDelegate>'。 然后你可以覆盖setDelegate并确保委托传递conformsToProtocol。 但是,您将丢失此处的编译时检查,并且仅对conformsToProtocol进行运行时检查
所以,那里! 工作..并设法有编译时警告..
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
这是一个相当令人困惑的问题,所以请原谅我,如果我错过了这一点,但看起来你的三个不同的继承级别每个都有不同的委托要求,每个代表都必须遵循不同的协议,所以它会是一个解决方案,将每个级别的委托作为一个不同名称的ivar,并作为一个不同的参考?
例如,您的基类将具有其delegate
,您已决定将其分配给第一个继承的子类。 它有自己的委托,名为level1delegate
,下一级别有另一个委托,名为level2delegate
。 如果该对象符合所有三个协议,您当然可以将所有这三个设置为同一个对象。
基本上,没有规则说代表必须被称为“代表”,所以不要因为不打破它而撕裂自己。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.