Iphone - performSelector: withObject: afterDelay: 'не найден в протоколах?
У меня это внутри класса
[delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0];
и я имею эту ошибку
предупреждение: '-performSelector: withObject: afterDelay:' не найден в протоколе (ых)
Я не могу понять, что может быть неправильно.
любые подсказки?
спасибо.
Ответы
Ответ 1
Ваша проблема в том, что вы указали свою переменную экземпляра делегата как:
id<SomeProtocol> delegate;
Правильно? Это означает, что средство проверки времени компиляции будет искать методы только в протоколе <SomeProtocol>
. Однако performSelector:withObject:afterDelay:
объявляется на NSObject
. Это означает, что вы должны объявить ivar как:
NSObject<SomeProtocol> * delegate;
Это говорит о том, что он должен быть NSObject
, который соответствует <SomeProtocol>
, в отличие от любого объекта, который соответствует <SomeProtocol>
. Это должно избавиться от вашего предупреждения, и вам не нужно делать кастинг.
Ответ 2
Попробуйте сначала набросать делегат на свой класс, затем вызовите performSelector:withObject:afterDelay
:
[(SomeClass *) delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0];
Предполагая, что ваш delegate
имеет тип id
, вам нужно указать время выполнения, которое на самом деле наследует объект от NSObject
(где определяется метод performSelector:withObject:afterDelay:
), отбрасывая его в класс ' тип.
Ответ 3
Несмотря на то, что приведенный NSObject *
персонаж, созданный Дейвом, будет работать, более чистый альтернативный способ позволяет людям использовать протоколы, как и следовало ожидать, - вы можете самим протоколом заявить, что он поддерживает протокол NSObject.
NSObject - это не просто реализация, но также протокол, включающий все варианты executeSelector: method. Поэтому вы можете просто объявить в своем протоколе, что вы поддерживаете NSObject, как и любой другой класс, поддерживающий протокол:
@protocol MyProtocol <NSObject>
И предупреждения компилятора исчезнут (при условии, что вы импортировали определение протокола).
Обратите внимание, что это означает, что каждый, кто заявляет о поддержке вашего протокола, в значительной степени должен быть NSObject или наследовать множество методов. Но все классы, используемые в программировании на iPhone, получены из NSObject из-за практических соображений, поэтому, как правило, это не проблема.
EDIT:
Оказывается, -performSelector:withObject:afterDelay:
не находится в протоколе NSObject (те, у кого нет задержки). Поскольку для всех, использующих ваш протокол, все же лучше, если они могут просто использовать идентификатор для ссылки на тип протокола, я все равно использую протокол для его решения, но вам придется объявить расширение для протокола NSObject самостоятельно. Поэтому в заголовке для вашего файла вы можете добавить что-то вроде:
@protocol MyProtocolNSObjectExtras <NSObject>
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
@end
@protocol MyProtocol <NSObjectExtras>
....
@end
Затем вы получаете все те же преимущества, что и ранее.
Ответ 4
Вам нужно передать объект делегата фактическому классу, который вы работаете, чтобы иметь методы. Видно, что делегат может показывать только методы, определенные в протоколе. performSelector: withObject: не метод, определенный в протоколе.
[(CLASS*)delegate performSelector:@selector(doStuff:) withObject:myObject afterDelay:2.0];
Ответ 5
[NSTimer scheduledTimerWithTimeInterval:2
target:self
selector:@selector(doStuff)
userInfo:nil
repeats:NO];
Попробуйте предположить, что вам нужен только таймер