Параметры методов, методы протокола, делегаты и вызовы RespondsToSelector

У меня есть такой код:

MyClass.h

#import "MyOtherClass.h"

@interface MyClass : NSObject<SomeProtocol, MyOtherClassDelegate> {
...
}

MyClass.m

+ (void) doThis {
   [someObject doThisWithDelegate:self];  // someObject is MyOtherClass type
}

MyOtherClass.h:

@protocol MyOtherClassDelegate <NSObject>
@required
// Some methods
@end

- (void) doThisWithDelegate:(id<SomeOtherProtocol>)delegate;

MyOtherClass.m:

- (void) doThisWithDelegate:(id<SomeOtherProtocol>)delegate {
    if ([delegate respondsToSelector:@selector(myProtocolMethod:error:)]) do things;
}

Делая так, у меня есть следующие предупреждения во время компиляции:

на линии [someObject doThisWithDelegate:self];

"Incompatible pointer types sending Class to parameter of type id<SomeOtherProtocol>"

на метод, объявленный в MyOtherClass.h:

"Passing argument to parameter 'delegate' here"

Раньше я не вводил параметр id (с id<SomeOtherProtocol>) она была просто "одна" (id). Я заметил, что тест:

if ([delegate respondsToSelector:@selector(myProtocolMethod:error:)])

вернул FALSE (но, конечно, методы реализованы и объявлены в делегате).

Поэтому я решил попытаться заставить id тип, чтобы соответствовать протоколу, который заставляет меня это предупреждение во время компиляции.

Что здесь происходит?
Почему у меня есть эта ошибка, и почему respondsToSelector не вернуть ИСТИНА?

3 ответа

Решение

Проблема заключалась в том, что я объявляю doThis Метод как метод класса, а не метод экземпляра. Так self недопустимо при передаче в качестве параметра.

Если вы хотите позвонить respondsToSelector: на имущество с типом id<SomeProtocol> затем убедитесь, что ваш протокол соответствует NSObject протокол.

Пример:

@protocol SomeOtherProtocol <NSObject>
// methods
@end

Это позволит вам сделать:

if ([self.delegate respondsToSelector:@selector(myProtocolMethod:error:)]) {
}

Это предполагает delegate определяется как:

@property (nonatomic, weak) id<SomeOtherProtocol> delegate;

Сначала убедитесь, что вы соответствуете, responsedsoSelector является частью NSObject.

Во-вторых, я бы проверил, правильно ли я установил свойство делегата.

Эта строка:

if ([self.delegate respondsToSelector:@selector(myProtocolMethod:error:)]) 

должно работать, так как делегат свойства указывает на объект, который должен иметь myProtocolMethod: error:....

Я, вероятно, отладил бы с точкой останова или тестом на установщике для делегата:

-(void)setDelegate:(id)delegate 
{
NSLog("We are setting a delegate!: %@", [delegate description]);
 _delegate = delegate;
}

Если, когда вы запускаете свое приложение, вы видите "Мы настраиваем…" после того, как вы выполнили свою строку if или если вы ее вообще не видите, то вы знаете, в чем проблема.

Другие вопросы по тегам