Ответ 1
Опустите отрицание из вашего оператора if
:
if ([self.delegate respondsToSelector:@selector(gameStarted)]) {
...
}
i создал делегат для класса
@protocol gameDelegate <NSObject>
@optional
-(void)gameStarted;
@required
@end
теперь в моем игровом объекте я назвал этот метод:
[self.delegate gameStarted];
так что теперь, если я инициирую этот объект где угодно и устанавливаю делегат, все работает нормально до тех пор, пока не будет вызван gameStated, потому что он не реализован в основном объекте, где создан игровой объект (поскольку его необязательный).
Я пробовал некоторые варианты этого
if(![self.delegate respondsToSelector: @selector(gameStarted)]) {
//[self.delegate gameStarted];
}
но это не работает для меня. любые идеи, как сделать это "действительно" необязательным?
заблаговременно
Опустите отрицание из вашего оператора if
:
if ([self.delegate respondsToSelector:@selector(gameStarted)]) {
...
}
Чтобы выполнить это быстро, я рекомендую следующее:
@objc protocol MyDelegate {
optional func optionalMethod()
}
class MyClass : MyDelegate {
// optionalMethod() does not have to be declared
}
Затем, чтобы вызвать optional
на вашем объекте delegate
, просто используйте if delegate.optionalMethod?(){}
Проверка того, что делегат реализует необязательный метод, а затем вызывает его как обычный шаблон, я использую макрос препроцессора SAFE_CALL
, который проверяет respondToSelector:
, а затем вызывает метод.
Макрос:
#define SAFE_CALL(obj,method) \
([obj respondsToSelector:@selector(method)] ? [obj method] : nil)
и он используется следующим образом:
SAFE_CALL(sourceDelegate, refresh)
// or
NSString *response = SAFE_CALL(object, responseValue)
Обратите внимание, что эта версия работает только с методами без параметров.
Первоначально он был реализован как функция C, но это вызывает предупреждения с утечками performSelector
при использовании ARC. В качестве макроса препроцессора он работает точно так, как ожидалось.