- (void)someMethod
{
if ( [delegate respondsToSelector:@selector(operationShouldProceed)] )
{
if ( [delegate operationShouldProceed] )
{
// do something appropriate
}
}
}
只有正式协议中的可选方法或非正式协议的方法才需要采取预防措施
这是什么意思?如果我使用正式协议,我可以使用[delegate myMethod]
?
答案 0 :(得分:81)
您只需在以下情况下使用它:检查对象是否实现了您要调用的方法。 通常当您拥有可选方法或非正式协议时,即可完成此操作。
当我编写必须与委托对象通信的代码时,我只使用过respondsToSelector
。
if ([self.delegate respondsToSelector:@selector(engineDidStartRunning:)]) {
[self.delegate engineDidStartRunning:self];
}
有时您会希望在返回的任何方法上使用respondsToSelector
,而id
或泛型NSObject
则不确定返回对象的类是什么。
答案 1 :(得分:45)
只是添加@kubi所说的,另一次我使用它的方法是在较新版本的框架中将方法添加到预先存在的类中,但我仍然需要向后兼容。例如:
if ([myObject respondsToSelector:@selector(doAwesomeNewThing)]) {
[myObject doAwesomeNewThing];
} else {
[self doOldWorkaroundHackWithObject:myObject];
}
答案 2 :(得分: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
该协议的给定和实例我们可以安全地调用任何所需的方法。
id <MyProtocol> myObject = ...
[myObject requiredMethod];
但是,可能会或可能不会实现可选方法,因此您需要在运行时进行检查。
if ([myObject respondsToSelector:@selector(optionalMethod)])
{
[myObject optionalMethod];
}
执行此操作可以防止使用无法识别的选择器崩溃。
此外,你应该将协议声明为NSObjects的扩展,即
@protocol MyProtocol <NSObject>
是因为NSObject协议声明了respondsToSelector:
选择器。否则XCode会认为调用它是不安全的。
答案 3 :(得分:2)
老问题,但我已经学会了使用像addTarget这样的东西非常谨慎:@selector(fu :)因为XCODE没有检查方法名称也没有包含在重构中。这已经给我带来了一些麻烦。所以现在我把它作为一个习惯,总是在responsedsToSelector中添加像addTarget或addObserver这样的东西 - 像这样检查:
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中意外崩溃。