When to use responsesToSelector in objective-c

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

The documentation says:

Precautions are only required for optional methods in the formal protocol or informal protocol methods.

What does it mean? If I use a formal protocol, can I just use [delegate myMethod] ?

+57
ios objective-c
Sep 12 '10 at 23:17
source share
4 answers

You use it to a large extent only when you think you need to: check whether the object implements the method that you are going to call. This is usually done when you have optional methods or an unofficial protocol.

I have ever used respondsToSelector when I write code that should communicate with a delegate object.

 if ([self.delegate respondsToSelector:@selector(engineDidStartRunning:)]) { [self.delegate engineDidStartRunning:self]; } 

Sometimes you would like to use respondsToSelector for any returned method and id or generic NSObject , where you are not sure what class of the returned object is.

+73
Sep 12 '10 at 23:29
source share

Just to add to what @kubi said, another time I use it when a method was added to an existing class in a newer version of the frameworks, but I still need to be backward compatible. For example:

 if ([myObject respondsToSelector:@selector(doAwesomeNewThing)]) { [myObject doAwesomeNewThing]; } else { [self doOldWorkaroundHackWithObject:myObject]; } 
+45
Sep 12 '10 at 23:33
source share

As kubi respondsToSelector is mentioned, it is usually used when you have an instance of a method that conforms to the protocol.

 // Extend from the NSObject protocol so it is safe to call `respondsToSelector` @protocol MyProtocol <NSObject> // @required by default - (void) requiredMethod; @optional - (void)optionalMethod; @end 

Given an instance of this protocol, we can safely call any required method.

 id <MyProtocol> myObject = ... [myObject requiredMethod]; 

However, optional methods may or may not be implemented, so you need to check them at runtime.

 if ([myObject respondsToSelector:@selector(optionalMethod)]) { [myObject optionalMethod]; } 

Doing this will prevent a failure with an unrecognized selector.




In addition, you must declare the protocols as an extension of NSObjects, i.e.

 @protocol MyProtocol <NSObject> 

This is because the NSObject protocol declares the respondsToSelector: selector. Otherwise, Xcode will consider it unsafe.

+11
03 Feb '14 at 9:12
source share

An old question, but I learned to be very careful using things like addTarget: @selector (fu :), because the method name has not been verified and is not included in XCODE refactoring. This has already caused me trouble. So now I have made it a habit to always embed things like addTarget or addObserver in responsesToSelector-Check, for example:

 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); } 

I know that this is not very elegant, but I would rather add the template code than the unexpected crash of my applications in the App Store.

+2
Oct. 21 '12 at 12:31 on
source share



All Articles