когда использовать respondsToSelector в Objective-С
- (void)someMethod
{
if ( [delegate respondsToSelector:@selector(operationShouldProceed)] )
{
if ( [delegate operationShouldProceed] )
{
// do something appropriate
}
}
}
The документация говорит:
меры предосторожности необходимы только для факультативных методов в формальном протоколе или методов неформального протокола
что это значит? Если я использую формальный протокол, я могу просто использовать [delegate myMethod]?
4 ответов:
вы используете его в значительной степени только тогда, когда вы думаете, что вам нужно: чтобы проверить, реализует ли объект метод, который вы собираетесь вызвать. обычно это делается, когда у вас есть дополнительные методы или неофициальный протокол.
Я только когда-либо использовать
respondsToSelectorкогда я пишу код, который должен взаимодействовать с объектом делегата.if ([self.delegate respondsToSelector:@selector(engineDidStartRunning:)]) { [self.delegate engineDidStartRunning:self]; }вы иногда хотели бы использовать
respondsToSelectorна любой метод, который возвращает иidили genericNSObjectгде вы не уверен, что класс возвращаемого объекта.
просто чтобы добавить к тому, что сказал @kubi, в другой раз я использую его, когда метод был добавлен в ранее существующий класс в более новой версии фреймворков, но мне все равно нужно быть обратно совместимым. Например:
if ([myObject respondsToSelector:@selector(doAwesomeNewThing)]) { [myObject doAwesomeNewThing]; } else { [self doOldWorkaroundHackWithObject:myObject]; }
как упоминал Куби
respondsToSelectorобычно используется, когда у вас есть экземпляр метод, который соответствует протоколу.// Extend from the NSObject protocol so it is safe to call `respondsToSelector` @protocol MyProtocol <NSObject> // @required by default - (void) requiredMethod; @optional - (void)optionalMethod; @endучитывая и экземпляр этого протокола мы можем безопасно вызвать любой необходимый метод.
id <MyProtocol> myObject = ... [myObject requiredMethod];однако дополнительные методы могут быть реализованы или не реализованы, поэтому вам нужно проверить во время выполнения.
if ([myObject respondsToSelector:@selector(optionalMethod)]) { [myObject optionalMethod]; }это предотвратит сбой с непризнанным селектором.
кроме того, почему вы должны объявить протоколы как расширение NSObjects, т. е.
@protocol MyProtocol <NSObject>это потому, что протокол NSObject объявляет
respondsToSelector:селектор. В противном случае XCode будет думать, что это небезопасно называть его.
старый вопрос, но я научился быть очень осторожным с использованием таких вещей, как addTarget:@selector(fu:) потому что имя метода не проверяется и не включается в рефакторинг с помощью XCODE. Это уже доставило мне немало хлопот. Так что теперь я сделал это привычкой всегда добавьте вещи, как addTarget или методов addObserver в respondsToSelector-проверить вот так:
if([self respondsToSelector:@selector(buttonClicked:)]){ [self.button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; }else{ DebugLog(@"Warning - a class or delegate did not respond to selector in class %@", self); }Я знаю, что это не очень элегантно, но я бы предпочел добавить какой-то шаблонный код, чем иметь неожиданный сбой моих приложений в магазин app Store.
Comments