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 g开发者_运维问答ets 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
Omit the negation from your if
statement:
if ([self.delegate respondsToSelector:@selector(gameStarted)]) {
...
}
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?(){}
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.
精彩评论