Переопределяющие свойства, которые соответствуют протоколам - PullRequest
10 голосов
/ 05 марта 2011

Кажется, я получаю новую ошибку при использовании LLVM Compiler 2.0, которого у меня раньше не было.

У меня есть протокол с именем DTGridViewDelegate , определенный как:

@protocol DTGridViewDelegate <UIScrollViewDelegate>

У меня есть свойство с именем delegate в DTGridView (подкласс UIScrollView, который сам по себе имеет свойство delegate).Это определяется как:

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

Теперь я получаю сообщение:

DTGridView.h:116:63: error: property type 'id<DTGridViewDelegate>' is incompatible with type 'id<UIScrollViewDelegate>' inherited from 'UIScrollView'

Поскольку я сказал, что DTGridViewDelegate соответствуетдля UIScrollViewDelegate я подумал, что было бы нормально переопределить это свойство таким образом, и действительно, это первый компилятор, который предположил, что есть проблема.

Я исправил ошибку, объявив свойство следующим образом:

@property (nonatomic, assign) IBOutlet id<DTGridViewDelegate, UIScrollViewDelegate> delegate;

Мне интересно, это проблема с компилятором?

Ответы [ 2 ]

8 голосов
/ 05 марта 2011

Ваша установка выглядит так же, как и в случае наследования UITableView от UIScrollView.Протокол UITableViewDelegate наследуется от протокола UIScrollViewDelegate.

Я настроил следующее, которое прекрасно компилируется:

// .h
@protocol ParentClassDelegate
-(NSString *) aDelegateMethod;
@end

@interface ParentClass : NSObject {
    id delegate;
}
@property(nonatomic, assign) IBOutlet id <ParentClassDelegate> delegate;
@end

//.m
@implementation ParentClass
@synthesize delegate;

-(id) delegate{
    return @"Parent delegate";
}//-------------------------------------(id) delegate------------------------------------

-(void) setDelegate:(id)someObj{
    delegate=someObj;
}//-------------------------------------(id) setDelegate------------------------------------
@end

//.h
@protocol ChildClassDelegate <ParentClassDelegate>
-(NSArray *) anotherDelegateMethod;
@end

@interface ChildClass : ParentClass{
}
@property(nonatomic, retain) IBOutlet id <ChildClassDelegate> delegate;
@end

//.m
@implementation ChildClass
//@synthesize delegate;

-(id) delegate{
    return @"childDelegate";
}//-------------------------------------(id) delegate------------------------------------

-(void) setDelegate:(id)someObj{
    delegate=someObj;
}//-------------------------------------(id) setDelegate------------------------------------

@end

Не уверен, что является причиной вашей проблемы.Я хотел бы отметить, что в заголовке протокол UITableViewDelegate выглядит следующим образом:

@protocol UITableViewDelegate<NSObject, UIScrollViewDelegate>

... поэтому, возможно, компилятору иногда нравятся более явные вещи.

Я бы предложил очистить и собрать.Это решает много проблем.

5 голосов
/ 05 марта 2011

Поскольку формальной спецификации языка Objective C нет, невозможно сказать, правильно ли работает компилятор. Все, что мы можем сказать, это то, что у gcc от Apple, похоже, нет проблем с описанным выше сценарием, хотя это концептуально несостоятельно, поскольку оно может нарушить замену Лискова , поскольку delegate является ковариантным от UIScrollView до DTGridView (хотя ковариация - такая же проблема). Что произойдет, если вы передадите DTGridView коду, ожидающему UIScrollView, который затем установит delegate для объекта, который соответствует UIScrollViewDelegate, но не DTGridViewDelegate?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...