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];

Попробуйте предположить, что вам нужен только таймер