我正在开发一个iOS应用程序,我有一个屏幕,显示一些相关搜索的过滤器。现在我已经将所有这些过滤器都设置为自定义UIViews,因为它们都具有相当不同的UI,并且必须在不同的屏幕上重复使用。尽管它们存在差异,但它们都提供了一个与视图控制器管理它们的通用接口,因此视图控制器并不关心filterView的功能和方式。它只关心将一些数据传递给他们并通过他们所有人共有的属性来检索他们的状态。它们都有不同的类,它们是FilterView的子类,是UIView的子类。这个FilterView类提供了一个所有这些子类都采用的接口。
这种方法工作正常,但问题是filterView应该呈现的所有方法和属性都在基类FilterView中声明,如果某个特定的过滤器没有实现行为,则默认为由它的超类FilterView。我不想要这个。我希望每个FilterView子类都需要在FilterView API上提供实现,否则提供它们自己的默认值而不是超类的默认值。
如果我使用协议来实现这种行为,我就失去了所有这些类强制为UIViews的能力,这也是一个要求。
您能否建议我应该使用哪种设计模式来更好地管理所有不同的FilterView子类。
答案 0 :(得分:2)
好吧,如果您认为所有过滤器对象都需要提供UIView
而不是显式为1,那么您可以将此要求添加到协议中。例如:
@protocol FilterObject
- (UIView *)viewForFilter;
@end
// Swift
protocol FilterObject {
func viewForFilter() -> UIView
}
然后在实际 UIView
的课程中,就像这样实现它:
- (UIView *)viewForFilter {
return self;
}
// Swift
func viewForFilter() -> UIView {
return self
}
为了完整起见,你也可以强迫"强迫"通过在调用基本实现时抛出异常来实现子类中的方法的要求:
- (void) methodWithoutBaseImplementation {
// this goes in the base class
[NSException raise:NSInternalInconsistencyException format:@"This method needs to be implemented by subclasses! - %@", NSStringFromSelector(_cmd)];
}
// Swift
func methodWithoutBaseImplementation() {
NSException.raise(NSInternalInconsistencyException, format:"This method needs to be implemented by subclasses! - \(__FUNCTION__)")
}
这种模式使Objective-C / Swift classess" abstract"可以在一些外部库中发挥作用。请注意,这在Swift中很难实现,因为它没有动态分派 - 这意味着如果将子类转换为基类并调用方法,则将调用基本实现。 我建议反对它,因为协议方法更安全,因为它不会创建一个崩溃应用程序的路径。我添加了这个例子只是为了说明可能性和完整性。
答案 1 :(得分:0)
使用非可选方法定义协议 - "默认情况下,协议中声明的所有方法都是必需的方法。这意味着任何符合协议的类都必须实现这些方法。" 定义一个声明它实现协议的类。 现在,当编写父类的子类时,如果强制方法没有实现,编译器会将其标记为错误
在超级课程中你可以写
//In super class
- (id)someMethod:(aObject*)param
{
[self doesNotRecognizeSelector:_cmd];
return nil;
}
如果子类不实现此方法且您不需要致电
,您的应用就会崩溃[super someMethod: param];
答案 2 :(得分:0)
通过在名为Filter
的协议中定义公共接口,然后将FilterView定义为:
typealias FilterView = UIView & Filter