Как разрешить "no known instance method for selector" выполнитьSelector: withObject: afterDelay: '"при переходе на ARC?

Инструмент миграции ARC отказывается принять этот код до начала миграции:

[self.delegate performSelector:@selector(overlayDismissed:) withObject:self afterDelay:0];

Делегат вынужден реализовать этот метод с протоколом, и он должен работать нормально:

@protocol OverlayDelegate <NSObject>
- (void)overlayDismissed:(Overlay*)overlay;
@end

@interface Overlay : UIImageView {
    id<OverlayDelegate> delegate;
}

@property (nonatomic, assign) id<OverlayDelegate> delegate;

Что случилось с ARC? Почему это говорит мне, что "нет известного метода экземпляра для селектора" performSelector: withObject: afterDelay: '?

Ответы

Ответ 1

ARC не вызывает этого - он просто разоблачает его. Этот метод определен в NSObject, но id работает не только как NSObject (поэтому вы должны быть более конкретным, чем просто "id" ). Измените свой код на это:

@interface Overlay : UIImageView {
    NSObject<OverlayDelegate> *delegate;
}

@property (nonatomic, assign) NSObject<OverlayDelegate> *delegate;

Ответ 2

Простой, ваш объект имеет тип id и соответствует протоколу NSObject. Однако этот протокол не объявляет performSelector:withObject:afterDelay:, поэтому ARC не знает, что делает этот метод, и если он должен что-то сохранить. Либо используйте NSObject, либо передайте его до вызова метода.

Ответ 3

Я понял, что литье делегата в NSObject * решает проблему:

[self.delegate performSelector:@selector(overlayDismissed:) withObject:self afterDelay:0];

По какой-то странной причине автозаполнение даже не придумало -performSelector:withObject:afterDelay:, поэтому мне пришлось вводить его вручную. Вместо этого он предложил только -performSelector: и -performSelector:withObject:withObject:

Я предполагаю, что просто глупо использовать id как тип для делегатов в Objective-C, и я никогда не знал, почему все, включая меня, делают это, а не просто определяют его как NSObject. Тем не менее, мой протокол даже сказал, что тот, кто соответствует этому протоколу, также должен соответствовать протоколу NSObject, делая это: OverlayDelegate <NSObject> - и все же компилятор не получил его.

Так что пока я доволен, что он работает с актерским составом, но он чувствует, как есть старую рыбу.

Ответ 4

Я встретил ошибку:

Неизвестный метод класса для селектора соответствуетToProtocol:

Причина в том, что: имя файла не равно имени класса с @interface и @implementation.