Reputation: 25244
i created a delegate for a class
@protocol gameDelegate <NSObject>
@optional
-(void)gameStarted;
@required
@end
now in my game object i called this method:
[self.delegate gameStarted];
so now, if i initiate this object anywhere and set the delegate everything works fine until the gameStated gets called, because its not implemented in the main object where the game object is created (because its optional).
i tried some variations of this
if(![self.delegate respondsToSelector: @selector(gameStarted)]) {
//[self.delegate gameStarted];
}
but this is not working for me. any ideas how to make this "really" optional?
thanks in advance
Upvotes: 12
Views: 8291
Reputation: 1841
To accomplish this in swift, I recommend the following:
@objc protocol MyDelegate {
optional func optionalMethod()
}
class MyClass : MyDelegate {
// optionalMethod() does not have to be declared
}
Then to call the optional
on your delegate
object, simple use if delegate.optionalMethod?(){}
Upvotes: 1
Reputation: 2010
Checking if a delegate implements an optional method and then calling it is such a common pattern that I use a preprocessor macro SAFE_CALL
that checks respondToSelector:
and then calls the method.
The macro is:
#define SAFE_CALL(obj,method) \
([obj respondsToSelector:@selector(method)] ? [obj method] : nil)
and it is used like this:
SAFE_CALL(sourceDelegate, refresh)
// or
NSString *response = SAFE_CALL(object, responseValue)
Note this version works only with methods with no parameters.
Originally it was implemented as a C function, but that causes warnings with performSelector
leaks when using ARC. As a preprocessor macro it works exactly as expected.
Upvotes: 0
Reputation: 135548
Omit the negation from your if
statement:
if ([self.delegate respondsToSelector:@selector(gameStarted)]) {
...
}
Upvotes: 18