何时在objective-c中使用respondsToSelector

Tah*_*aho 65 objective-c ios

- (void)someMethod
{
    if ( [delegate respondsToSelector:@selector(operationShouldProceed)] )
    {
        if ( [delegate operationShouldProceed] )
        {
            // do something appropriate
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

文件说:

只有正式协议中的可选方法或非正式协议的方法才需要采取预防措施

这是什么意思?如果我使用正式的协议,我可以使用[delegate myMethod]

kub*_*ubi 84

您只需在以下情况下使用它:检查对象是否实现了您要调用的方法.通常,当您有可选方法或非正式协议时,这会完成.

我只respondsToSelector在编写必须与委托对象通信的代码时使用过.

if ([self.delegate respondsToSelector:@selector(engineDidStartRunning:)]) {
        [self.delegate engineDidStartRunning:self];
    }
Run Code Online (Sandbox Code Playgroud)

有时您会想要respondsToSelector在任何返回的方法上使用,id或者NSObject在您不确定返回对象的类是什么的情况下使用.

  • `self.delegate`与调用`[self delegate]`完全相同.在我的代码中,`[self.delegate someMethod]`和`[_delegate someMethod]`之间没有区别,但是我倾向于使用点语法,因为它在我的脑海中保持直线,哪些变量是我所在的方法的局部变量这是实例变量. (2认同)

Dav*_*ong 46

只是为了添加@kubi所说的,另一次我使用它的方法是在新版本的框架中将方法添加到预先存在的类中,但我仍然需要向后兼容.例如:

if ([myObject respondsToSelector:@selector(doAwesomeNewThing)]) {
  [myObject doAwesomeNewThing];
} else {
  [self doOldWorkaroundHackWithObject:myObject];
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*ert 13

正如您所提到的kubi respondsToSelector通常在您拥有符合协议的方法实例时使用.

// Extend from the NSObject protocol so it is safe to call `respondsToSelector` 
@protocol MyProtocol <NSObject> 

// @required by default
- (void) requiredMethod;

@optional

- (void)optionalMethod;

@end
Run Code Online (Sandbox Code Playgroud)

给定和该协议的实例,我们可以安全地调用任何所需的方法.

id <MyProtocol> myObject = ... 
[myObject requiredMethod];
Run Code Online (Sandbox Code Playgroud)

但是,可能会或可能不会实现可选方法,因此您需要在运行时进行检查.

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

这样做可以防止无法识别的选择器崩溃.


此外,你应该将协议声明为NSObjects的扩展,即

@protocol MyProtocol <NSObject> 
Run Code Online (Sandbox Code Playgroud)

是因为NSObject协议声明了respondsToSelector:选择器.否则XCode会认为调用它是不安全的.