tags:

views:

186

answers:

2

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?

+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
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
+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
nice suggestions :)
Kevlar