代码之家  ›  专栏  ›  技术社区  ›  n00bProgrammer

使两个协议方法互斥(实现一个或另一个,而不是同时实现两个)

  •  0
  • n00bProgrammer  · 技术社区  · 10 年前

    假设我已经为一个子类定义了一个协议 UIView 如下所示:

    @protocol MyCustomViewDelegate <NSObject>
    
    - (NSString*) titleForItemAtIndex;
    
    - (UIImage*) imageForItemAtIndex;
    
    @end
    

    我希望实现委托方法的类只实现一个,而不是同时实现两个委托方法。如果代理执行 titleForItemAtIndex ,它必须 不是 使生效 imageForItemAtIndex ,反之亦然。如果两个方法都由委托类实现,则编译器必须抛出警告(或以其他方式向程序员传达警告)。这可能吗?

    2 回复  |  直到 10 年前
        1
  •  4
  •   Andrea    10 年前

    您可以询问委托实例是否响应特定选择器:

        if ([self.delegate respondToSelector:@selector(titleForItemAtIndex)]) {
            NSString * title = [title titleForItemAtIndex];
        }
        else if ([self.delegate respondToSelector:@selector(imageForItemAtIndex)]) {
            UIImage * title = [title imageForItemAtIndex];
    
        } 
    

    这还需要将委托方法标记为 @optional 在协议声明中。使用此条件,可以保证第一个方法优先于第二个方法。
    您可以再添加一个 else 如果没有调用它们,则抛出异常。

        2
  •  1
  •   GoodSp33d    10 年前

    我认为不可能抛出编译器错误。但仍然可以在运行时引发异常。您可以使用 NSAssert 并确保在运行时只实现一个方法。这不会引发编译器错误,但会导致应用程序崩溃,并显示一个日志,说明只应实现一个方法。

    // Checks for titleForItemAtIndex
    if ([self.delegate respondToSelector:@selector(titleForItemAtIndex)])
    {
        // Delegate has implemented titleForItemAtIndex.
        // So it should not be implementing imageForItemAtIndex
        // Below assert will check this
        NSAssert(![self.delegate respondToSelector:@selector(imageForItemAtIndex)], @"Delegate must not respond to imageForItemAtIndex");
        // Now that condition is checked. Do anything else as needed below.
    }
    
    // Checks for imageForItemAtIndex
    if ([self.delegate respondToSelector:@selector(imageForItemAtIndex)]) {
        // Delegate has implemented imageForItemAtIndex.
        // So it should not be implementing titleForItemAtIndex
        // Below assert will check this
        NSAssert(![self.delegate respondToSelector:@selector(titleForItemAtIndex)], @"Delegate must not respond to titleForItemAtIndex");
        // Now that condition is checked. Do anything else as needed below.
    }
    

    另一种方法是为两种方法创建单独的协议,并使用相同的协议 if assert 条件,但具有 conformsToProtocol 如果有很多互斥的方法,最好创建单独的协议。

    推荐文章