objc несовместимый тип указателя с наследованием протокола
Я работаю с Xcode версии 5.1, iOS SDK версии 7.1. Вот несколько примеров объявлений в одном файле:
@protocol A <NSObject>
@end
@protocol B <A>
@end
@interface SomeObject : NSObject <B>
@end
@interface SomeContainer : NSObject
- (id<A>)pop;
@end
Xcode генерирует предупреждение в следующем коде:
SomeContainer *container = [[SomeContainer alloc] init];
SomeObject *obj = [container pop]; // Warning: Initializing 'SomeObject *__strong' with and expression of incompatible type 'id<A>'
Я знаю, что приведение типов избавит от предупреждения, однако я не понимаю, зачем мне это нужно. SomeObject должен реализовывать все, что объявлено в протоколе A. Есть ли что-то, чего мне не хватает? Любое объяснение будет с благодарностью.
1 ответ
Вероятно, это потому, что SomeObject
это нечто большее, чем просто id<A>
, Это похоже на инициализацию объекта производного класса с указателем на базовый класс. Вы можете инициализировать экземпляр id<A>
с SomeObject
но когда вы делаете это наоборот, вы получаете предупреждение, которое гласит:"Эй, приятель, ты только что назначил базу для производного, то есть что-то, что присутствует в производном (SomeObject *)
может быть пропущено в базе id<A>
"
например SomeObject
может содержать метод foo
которого нет в протоколе A
, но теперь после того, как ваше назначение, если вы отправите foo
сообщение для obj
может произойти сбой, потому что id<A>
не обязательно имеет этот метод. Это может, если это также экземпляр SomeObject
, но это может быть что угодно, что ОБЯЗАТЕЛЬНО отвечает только на методы, объявленные в A
,
Я надеюсь, что все это имеет смысл