为什么在obj-c中调用该方法时,未实现的可选协议方法会导致运行时错误?

Kev*_*lar 10 objective-c

我有两个类可以充当第三类的委托,并且都实现完全由可选方法构成的正式协议.其中一个类实现了所有内容,而另一个类只实现了我关心的几个方法.但是,在运行时,当我让第二个类充当第三个类的委托,并且第三个类最终调用该委托上的一个未实现的可选方法时,我得到一个运行时错误,主要是说"Target没有响应这个消息选择器." 我认为objective-c正确地处理了这个案例,并且如果该方法实际上没有在类上定义那么它就什么都不做.可能有一些我想念的东西?

Ben*_*tow 33

当您调用委托的可选方法时,您需要确保它在调用它之前响应选择器:

if ([delegate respondsToSelector:@selector(optionalMethod)])
    [delegate optionalMethod];
Run Code Online (Sandbox Code Playgroud)

  • 我怀疑,但我希望我不需要在整个代码中添加if-check.谢谢你的指针. (2认同)

Pet*_*wis 10

可选的协议方法只是意味着实现协议的对象不必实现有问题的方法 - 然后被调用者必须在调用之前检查对象是否实现了该方法(否则你会崩溃,如你所注意到的).这些NSObject HOM类别可能会有所帮助:

@implementation NSObject (Extensions)

- (id)performSelectorIfResponds:(SEL)aSelector
{
    if ( [self respondsToSelector:aSelector] ) {
        return [self performSelector:aSelector];
    }
    return NULL;
}

- (id)performSelectorIfResponds:(SEL)aSelector withObject:(id)anObject
{
    if ( [self respondsToSelector:aSelector] ) {
        return [self performSelector:aSelector withObject:anObject];
    }
    return NULL;
}

@end
Run Code Online (Sandbox Code Playgroud)

然后你可以简单地做:

[delegate performSelectorIfResponds:@selector(optionalMethod)];
Run Code Online (Sandbox Code Playgroud)