何时在objective-c中使用respondsToSelector
- (void)someMethod { if ( [delegate respondsToSelector:@selector(operationShouldProceed)] ) { if ( [delegate operationShouldProceed] ) { // do something appropriate } } }
该文件说:
预防措施仅适用于正式协议中的可选方法或非正式协议的方法
这是什么意思? 如果我使用正式的协议,我可以使用[delegate myMethod]
?
只有在您认为需要时,才会使用它:检查对象是否实现您要调用的方法。 通常这是当你有一个可选的方法或一个非正式的协议。
当我编写必须与委托对象通信的代码时,我只使用过respondsToSelector
。
if ([self.delegate respondsToSelector:@selector(engineDidStartRunning:)]) { [self.delegate engineDidStartRunning:self]; }
你有时会想要在任何返回的方法上使用respondsToSelector
,而在你不确定返回对象的类是什么的时候,你可能会使用id
或genericsNSObject
。
只是添加@kubi所说的,另外一次我使用的是在一个新版本的框架中将一个方法添加到一个预先存在的类中,但是我仍然需要向后兼容。 例如:
if ([myObject respondsToSelector:@selector(doAwesomeNewThing)]) { [myObject doAwesomeNewThing]; } else { [self doOldWorkaroundHackWithObject:myObject]; }
正如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
鉴于此协议的实例,我们可以安全地调用任何所需的方法。
id <MyProtocol> myObject = ... [myObject requiredMethod];
但是,可选的方法可能会或可能不会被实现,所以您需要在运行时检查。
if ([myObject respondsToSelector:@selector(optionalMethod)]) { [myObject optionalMethod]; }
这样做可以防止无法识别的select器崩溃。
另外,为什么你应该把协议声明为NSObject的扩展,
@protocol MyProtocol <NSObject>
是因为NSObject协议声明了respondsToSelector:
select器。 否则,XCode会认为调用它是不安全的。
老问题,但我已经学会了使用像addTarget的东西非常谨慎:@selector(fu :),因为方法名称没有被检查,也没有包含在重构由XCODE。 这已经造成了相当麻烦。 所以现在我已经习惯了将addTarget或addObserver等东西embedded到respondsToSelector中,像这样:
if([self respondsToSelector:@selector(buttonClicked:)]){ [self.button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; }else{ DebugLog(@"Warning - a class or delegate did not respond to selector in class %@", self); }
我知道它不是超优雅的,但我宁愿添加一些样板代码,而不是在App Store中意外崩溃我的应用程序。