I have two classes that can act as a delegate of a third class, and both implement a formal protocol made entirely of optional methods. One of the classes implements everything while another only implements a couple methods that i care about. However, at runtime when i have the second class act as the delegate to the third class, and the third class ends up calling one of the unimplemented optional methods on that delegate, i get a runtime error essentially saying "Target does not respond to this message selector." I thought that objective-c handled this case correctly, and that it would just do nothing if that method wasn't actually defined on the class. Might there be something i'm missing?
views:
186answers:
2
+6
A:
Hi Kevlar,
When you call an optional method of your delegate, you need to make sure it responds to the selector before calling it:
if ([delegate respondsToSelector:@selector(optionalMethod)])
[delegate optionalMethod];
Ben Gotow
2009-06-22 19:22:12
I suspected as much, but i was hoping i wouldn't need to add those if-checks all over the code. Thanks for the pointer.
Kevlar
2009-06-22 19:29:48
+4
A:
Optional protocol methods simply mean the object implementing the protocol does not have to implement the method in question - the callee then absolutely must check whether the object implements the method before calling (otherwise you'll crash, as you noticed). These NSObject HOM categories can be helpful:
@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
Then you can simply do:
[delegate performSelectorIfResponds:@selector(optionalMethod)];
Peter N Lewis
2009-06-23 04:43:47