Синтаксис для разрешения несовместимого типа свойства унаследованного делегата

В некотором коде, унаследованном мной, есть раздражающее предупреждение. Он объявляет протокол и затем использует его для указания делегата

@protocol MyTextFieldDelegate;

@interface MyTextField: UITextField
@property (nonatomic, assign) id<MyTextFieldDelegate> delegate;
@end

@protocol MyTextFieldDelegate <UITextFieldDelegate>
@optional
- (void)myTextFieldSomethingHappened:(MyTextField *)textField;
@end

Классы, которые используют myTextField реализуют MyTextFieldDelegate и вызывают его с помощью этого кода:

if ([delegate respondsToSelector:@selector(myTextFieldSomethingHappened:)])
{
    [delegate myTextFieldSomethingHappened:self];
}

Это работает, но создает (законное) предупреждение: warning: свойство type 'id' несовместимо с типом 'id', унаследованным от 'UITextField'

Вот решения, которые я придумал:

  • Удалить свойство. Это работает, но я получаю предупреждение "-myTextFieldSomethingHappened:" не найден в протоколах.
  • Отбросьте протокол целиком. Предупреждений нет, но вы также теряете семантические предупреждения, если забываете реализовать протокол в делегате.

Есть ли способ определить свойство делегата, чтобы компилятор был счастлив?

Ответ 1

попробовать:

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

Ответ 2

UITextField также получил свойство с именем delegate, но имеет другой тип. Просто переименуйте свойство delegate в другое.

Ответ 3

Найден ответ в UITableView.h.

UIScrollView имеет делегат имени свойства, а UITableView имеет одно и то же имя.

@protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>
// Your code
......

@end

Ответ 4

Исходная проблема заключается в том, что во время объявления свойства delegate не существует информации о наследовании MyTextFieldDelegate. Это вызвано форвардным объявлением протокола (@protocol MyTextFieldDelegate;).

Я столкнулся с той же проблемой, но с объявлением протокола в другом файле .h. В моем случае решение было просто для #import соответствующего заголовка.

В вашем случае вам просто нужно поменять порядок объявления:

@class MyTextField;

@protocol MyTextFieldDelegate <UITextFieldDelegate>
@optional
- (void)myTextFieldSomethingHappened:(MyTextField *)textField;
@end

@interface MyTextField : UITextField
@property (nonatomic, assign) id <MyTextFieldDelegate> delegate;
@end