Параметры методов, методы протокола, делегаты и вызовы 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 или если вы ее вообще не видите, то вы знаете, в чем проблема.