繁体   English   中英

Objective-C - 子类中委托的子类

[英]Objective-C — Subclass of delegate in subclass

这是一个相当复杂的继承层次结构,所以忍受我(我试图简化事情,而不是陈述我使用的确切情况,这更复杂): -

假设我创建了一个名为TextFieldUITextField子类,它是我自己的自定义增强通用文本字段。 现在,为了提供这种增强功能,在TextFieldinit方法中,我设置了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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM