2014-01-31 43 views
0

我已经构建了一个实现各种UI功能的UIViewController。它旨在让用户进行子类化,以便他们可以使用几种方法(如setContents:getContents)对其进行更新。UIViewController子类调用方法

在我的UIViewController中,当我点击一个按钮时,我想调用一个方法,以便用户在其子类showPicker中实现。

我想用户能够能够控制他们在这个方法中做什么,所以我想,他们应该只是实现它的子类中:

- (void)showPicker { 
    // Do what you want 
} 

为了做到这一点,我必须在原始UIViewController中添加一个同名的空白方法,然后将其添加到头文件中。

我想要做的就是如何继承UIViewController,然后执行viewWillAppear:并按照该方法进行操作。

如果我想允许用户控制当我的类内部的按钮被点击时发生了什么,这是否是正确的模式?我做这一切都错了吗?我应该使用代表吗?

回答

1

如果你想效仿UIViewController确实与viewWillAppear:,你需要在你的基类中添加的showPicker一个什么都不做的实现。 UIViewController.h表示viewWillAppear:具有不执行任何操作的默认实现。

代表会让您的基类和子类复杂化,而没有真正简化太多的回报。它们比抽象方法更接近通知。

这里

其他选项是做线沿线的东西:

if ([self canPerformSelector:@selector(showPicker)]) { 
    ... 
} 

它不给我喜欢尽可能多的编译时的安全性,但它是一种替代,并保持在大部分的责任基类。但是我发现它不像基类中的空方法实现那样可被发现。

如果您不希望在基类中使用抽象方法的空实现,那么协议可能更适合平衡可发现性和编译时安全性。

@protocol PickerProtocol <NSObject> 
- (void)showPicker; 
@end 

@interface SomeBaseClass : UIViewController 
    ... 
@end 

@implementation SomeBaseClass 

- (void)someBaseClassMethod { 
    if ([self conformsToProtocol:@protocol(Picker)]) { 
    [(id<PickerProtocol>)self showPicker]; 
    } 
} 

@end 

你的子类选择加入,宣称他们已经实施了协议,让编译器,如果你没有实现所有@required方法警告。

@interface MySubClass <PickerProtocol> 
    ... 
@end 

@implementation MySubClass 

- (void)showPicker { 
    ... 
} 

@end 

这允许编译器显示警告和代码完成。虽然它不像空基类方法那么简单,但它确实允许子类明确声明它们提供了一些行为。

如果这只是一种方法,那么我会使用空方法。如果你有一组应该一起实现的方法,我会使用协议。

+0

优秀的答案!我想我会坚持使用空方法,因为它只是我需要使用的一种方法。再次感谢! –

1

创建一个被设计为子类的类将会起作用并且没有错(大多数框架都依赖于这些类)。这对你来说是否是最好的选择取决于你期望如何使用这个类。

  • 你要提供这些方法的默认实现:如果

    子类是有道理的。

  • 您希望子类能够通过控制是否以及何时调用super来覆盖和替换默认实现。
  • 此消息仅与接收类相关,例如结果操作通常与控制器私有方法或属性交互。将它暴露给其他对象会引入它们之间的紧密耦合并违反单一责任原则。

在另一方面委托可能是一个更好的选择,如果:

  • 此行为是可选的。
  • 该信息是一个关注问题的一部分,不是派遣阶级的责任。也许控制者已经确定了用户的意图(“选择这个选项”),但是按照这个意图行事并不是它的工作。请注意,对象可以是其自己的代理(如果适用)(例如,为默认代理提供默认行为而不是默认行为。)
  • 一个对象从多个来源响应此消息是合理的。
  • 不重写发送对象上的行为很重要。尽管在UIKit中出现过多次,但“必须调用超级”并不是一个好的模式。

块也可能很适合接受小单元的自定义行为而不需要额外的类。