从子类 setDelegate 设置超类委托
Set superclass delegate from subclass setDelegate
我有一个超级class A,它有一个BaseModalViewControllerDelegate
协议和一个用于id<BaseModalViewControllerDelegate> delegate
的保留属性。
我还有 class B,A 的子 class,它有一个 ModalLoginDelegate
协议和一个保留 属性 用于 id<ModalLoginDelegate> delegate
现在,我将 B 的 setter 方法设置为 class 委托此方法:
-(void)setDelegate: (id<ModalLoginDelegate>)delegate
{
_delegate = delegate;
[super setDelegate: (id<BaseModalViewControllerDelegate>)delegate;
}
因此,存在实现这两种协议的 RootViewController,但它仅初始化 B class 并将自己设置为 B class 的委托,因为它不知道 B class 是 A.
的子class
您认为这是将 RootVC 设置为两种协议的委托的正确方法吗?谢谢
添加
将 B class 的协议设置为继承自 A class:
@protocol ModalLoginDelegate <BaseModalDelegate>
// delegate method of subclass
@end
现在,我的 RootVC 不必将自己设置为 BaseModalViewController 的委托。但是现在,当在我的 B class 中我想调用 superclass 的委托方法时,我正在这样做
if (self.loginDelegate)
{
[self.loginDelegate baseModalViewController: self willDismiss: YES];
}
我认为这不是一个非常干净的方法,所以我在 superclass -(void)pressedCloseButton;
中创建了一个 public 方法,它将执行此操作
-(void)pressedCloseButton
{
if (self.delegate)
{
[self.delegate baseModalViewController: self willDismiss: YES];
}
}
并且在子class中:
-(IBAction)closeBtnPressed: (id)sender
{
[super pressedCloseButton];
}
你觉得对吗?
更好的设计是为您的子class实现一个单独的委托属性,比如说loginDelegate
。在 subclass 中更改 属性 的类型不是很好的 OO 设计。大多数 OO 语言甚至不允许这样做。
这也确保了消耗 class 是 "aware" 涉及两个单独的委托协议。
RootVC
如果需要实现两个协议,则需要将自己设置为两个委托。您不能指望 class 不知道它需要实现哪些委托协议。如果 RootVC
认为它只处理基础 class 那么它不会设置 loginDelegate 并且不会实现该协议中的方法。
我完全不反对 Paulw11 在这里的回答,但有趣的是,Apple 自己也这样做了。
例子。 UIScrollView 有一个委托 属性
@property (weak, nonatomic) id <UIScrollViewDelegate> delegate;
子类 UITableView 有一个委托 属性
@property (weak, nonatomic) id <UITableViewDelegate> delegate;
当我们在 ObjC 中声明一个协议时,我们通常让该协议扩展 协议。
@protocol BaseModalViewControllerDelegate <NSObject>
-(void)doSomething;
-(NSString *)titleForThing;
@end
现在上面这个协议不仅有这里原型化的方法,还有 协议中的方法原型。它非常像这个协议是另一个协议的 'subclass',也继承了它的所有内容。
如果您使用第二个协议执行此操作
@protocol ModalLoginDelegate <BaseModalViewControllerDelegate>
-(void)doAnotherThing;
-(NSString *)titleForTheOtherThing;
@end
那么你在这里所做的将与 Apple 对 UITableView 和 UIScrollView 所做的完全一致,因为类型 id 的指针始终也是类型 id 的对象,就像UIButton* 将始终能够作为 UIView* 传入 ...
但如果不这样做,您的
就会出现根本性问题
-(void)setDelegate:(id<ModalLoginDelegate>)delegate
方法在那里,因为你假设这个对象符合 BaseModalViewControllerDelegate 协议,而你唯一确定的是它符合 ModalLoginDelegate 协议。某些继承的方法可能会使用 self.delegate 不响应的 BaseModalViewControllerDelegate 方法调用 self.delegate。
我希望这会有所帮助:)
我有一个超级class A,它有一个BaseModalViewControllerDelegate
协议和一个用于id<BaseModalViewControllerDelegate> delegate
的保留属性。
我还有 class B,A 的子 class,它有一个 ModalLoginDelegate
协议和一个保留 属性 用于 id<ModalLoginDelegate> delegate
现在,我将 B 的 setter 方法设置为 class 委托此方法:
-(void)setDelegate: (id<ModalLoginDelegate>)delegate
{
_delegate = delegate;
[super setDelegate: (id<BaseModalViewControllerDelegate>)delegate;
}
因此,存在实现这两种协议的 RootViewController,但它仅初始化 B class 并将自己设置为 B class 的委托,因为它不知道 B class 是 A.
的子class您认为这是将 RootVC 设置为两种协议的委托的正确方法吗?谢谢
添加
将 B class 的协议设置为继承自 A class:
@protocol ModalLoginDelegate <BaseModalDelegate>
// delegate method of subclass
@end
现在,我的 RootVC 不必将自己设置为 BaseModalViewController 的委托。但是现在,当在我的 B class 中我想调用 superclass 的委托方法时,我正在这样做
if (self.loginDelegate)
{
[self.loginDelegate baseModalViewController: self willDismiss: YES];
}
我认为这不是一个非常干净的方法,所以我在 superclass -(void)pressedCloseButton;
中创建了一个 public 方法,它将执行此操作
-(void)pressedCloseButton
{
if (self.delegate)
{
[self.delegate baseModalViewController: self willDismiss: YES];
}
}
并且在子class中:
-(IBAction)closeBtnPressed: (id)sender
{
[super pressedCloseButton];
}
你觉得对吗?
更好的设计是为您的子class实现一个单独的委托属性,比如说loginDelegate
。在 subclass 中更改 属性 的类型不是很好的 OO 设计。大多数 OO 语言甚至不允许这样做。
这也确保了消耗 class 是 "aware" 涉及两个单独的委托协议。
RootVC
如果需要实现两个协议,则需要将自己设置为两个委托。您不能指望 class 不知道它需要实现哪些委托协议。如果 RootVC
认为它只处理基础 class 那么它不会设置 loginDelegate 并且不会实现该协议中的方法。
我完全不反对 Paulw11 在这里的回答,但有趣的是,Apple 自己也这样做了。 例子。 UIScrollView 有一个委托 属性
@property (weak, nonatomic) id <UIScrollViewDelegate> delegate;
子类 UITableView 有一个委托 属性
@property (weak, nonatomic) id <UITableViewDelegate> delegate;
当我们在 ObjC 中声明一个协议时,我们通常让该协议扩展
@protocol BaseModalViewControllerDelegate <NSObject>
-(void)doSomething;
-(NSString *)titleForThing;
@end
现在上面这个协议不仅有这里原型化的方法,还有
如果您使用第二个协议执行此操作
@protocol ModalLoginDelegate <BaseModalViewControllerDelegate>
-(void)doAnotherThing;
-(NSString *)titleForTheOtherThing;
@end
那么你在这里所做的将与 Apple 对 UITableView 和 UIScrollView 所做的完全一致,因为类型 id
但如果不这样做,您的
就会出现根本性问题 -(void)setDelegate:(id<ModalLoginDelegate>)delegate
方法在那里,因为你假设这个对象符合 BaseModalViewControllerDelegate 协议,而你唯一确定的是它符合 ModalLoginDelegate 协议。某些继承的方法可能会使用 self.delegate 不响应的 BaseModalViewControllerDelegate 方法调用 self.delegate。 我希望这会有所帮助:)