首页 文章

子类或协议,如何?

提问于
浏览
0

我正在开发一个iOS应用程序,我有一个屏幕,显示一些相关搜索的过滤器 . 现在我已将所有这些过滤器作为自定义UIViews,因为它们都具有相当不同的UI,并且必须在不同的屏幕上重复使用 . 尽管存在差异,但它们都提供了一个与视图控制器管理它们的通用接口,因此视图控制器不关心filterView的功能和方式 . 它只涉及将一些数据传递给他们并通过所有人共有的属性检索他们的状态 . 它们都有不同的类,它们是FilterView的子类,是UIView的子类 . 此FilterView类提供了所有这些子类采用的接口 .

这种方法工作正常,但问题是filterView应该呈现的所有方法和属性都在基类FilterView中声明,如果某个特定的过滤器没有实现行为,则默认为其超类FilterView提供的行为 . 我不想要这个 . 我希望每个FilterView子类都需要在FilterView API上提供实现,否则提供它们自己的默认值而不是超类的默认值 .

如果我使用协议来实现这种行为,我将所有这些类的能力强制性地强制为UIViews,这也是一个要求 .

您能否建议我应该使用哪种设计模式来更好地管理所有不同的FilterView子类 .

3 回答

  • 0

    好吧,如果您认为所有过滤器对象都需要提供 UIView 而不是显式为1,则可以将此要求添加到协议中 . 例如 :

    @protocol FilterObject 
    
    - (UIView *)viewForFilter;
    
    @end
    
    // Swift
    protocol FilterObject {
        func viewForFilter() -> UIView
    }
    

    然后在实际 are 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“抽象”的模式可以在一些外部库中形成 . 请注意,这在Swift中很难实现,因为它没有动态调度 - 这意味着如果将子类强制转换为基类并调用方法,则将调用基本实现 . 我建议反对它,因为协议方法更安全,因为它不会创建一个崩溃应用程序的路径 . 我添加了这个例子只是为了说明可能性和完整性 .

  • 0

    使用非可选方法定义协议 - “默认情况下,协议中声明的所有方法都是必需的方法 . 这意味着符合协议的任何类都必须实现这些方法 . ”定义一个声明它实现协议的类 . 现在,当编写父类的子类时,如果没有实现强制方法,编译器会将其标记为错误

    在超级课程中你可以写

    //In super class
    - (id)someMethod:(aObject*)param
    {
         [self doesNotRecognizeSelector:_cmd];
         return nil;
    }
    

    如果子类不实现此方法而您不需要调用,则您的应用程序将崩溃

    [super someMethod: param];
    
  • 2

    现在可以通过在名为 Filter 的协议中定义公共接口,然后将FilterView定义为:

    typealias FilterView = UIView & Filter
    

相关问题