使两个Protocol方法独占(实现一个或另一个,而不是两者)

时间:2015-02-12 07:40:45

标签: ios objective-c

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

@protocol MyCustomViewDelegate <NSObject>

- (NSString*) titleForItemAtIndex;

- (UIImage*) imageForItemAtIndex;

@end

我希望实现委托方法的类只实现一个,而不是两个委托方法。如果代理人实施titleForItemAtIndex,则必须实施imageForItemAtIndex,反之亦然。如果委托类实现了这两种方法,则编译器必须发出警告(或以其他方式与程序员进行通信)。这可能吗?

2 个答案:

答案 0 :(得分:4)

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

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

    } 

这还要求您在协议声明中将委托方法标记为@optional。在这种情况下,您可以保证第一种方法在第二种方法上具有优先权 您可以再添加一个else,如果没有调用它们,则抛出异常。

答案 1 :(得分:1)

我认为不可能抛出编译器错误。但是仍然可以在运行时引发异常。您可以使用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如果您有许多互斥的方法,最好创建单独的协议。< / p>