когда использовать respondsToSelector в Objective-С



- (void)someMethod
{
if ( [delegate respondsToSelector:@selector(operationShouldProceed)] )
{
if ( [delegate operationShouldProceed] )
{
// do something appropriate
}
}
}


The документация говорит:




меры предосторожности необходимы только для факультативных методов в формальном протоколе или методов неформального протокола




что это значит? Если я использую формальный протокол, я могу просто использовать [delegate myMethod]?

455   4  

4 ответов:

вы используете его в значительной степени только тогда, когда вы думаете, что вам нужно: чтобы проверить, реализует ли объект метод, который вы собираетесь вызвать. обычно это делается, когда у вас есть дополнительные методы или неофициальный протокол.

Я только когда-либо использовать respondsToSelector когда я пишу код, который должен взаимодействовать с объектом делегата.

if ([self.delegate respondsToSelector:@selector(engineDidStartRunning:)]) {
        [self.delegate engineDidStartRunning:self];
    }

вы иногда хотели бы использовать respondsToSelector на любой метод, который возвращает и id или generic NSObject где вы не уверен, что класс возвращаемого объекта.

просто чтобы добавить к тому, что сказал @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

    Ничего не найдено.