Синтаксис для разрешения несовместимого типа свойства унаследованного делегата - PullRequest
11 голосов
/ 19 ноября 2011

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

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

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

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

  1. Удалить имущество. Это работает, но я получаю предупреждение '- myTextFieldSomethingHappened:' не найден в протоколе (ах)
  2. Отбросьте протокол полностью. Предупреждений нет, но вы также теряете семантические предупреждения, если забыли реализовать протокол в делегате.

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

Ответы [ 4 ]

30 голосов
/ 13 ноября 2012

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

@property (nonatomic, assign) id<UITextFieldDelegate,MyTextFieldDelegate> delegate;
5 голосов
/ 19 ноября 2011

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

4 голосов
/ 17 января 2013

Нашел ответ в UITableView.h.

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

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

@end
2 голосов
/ 10 июля 2014

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

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

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

@class MyTextField;

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

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