Вопрос

I am running with Xcode version 5.1, iOS SDK version 7.1. Here are some sample declarations all in the same file:

@protocol A <NSObject>
@end

@protocol B <A>
@end

@interface SomeObject : NSObject <B>
@end

@interface SomeContainer : NSObject
- (id<A>)pop;
@end

Xcode generates a warning in the following code:

SomeContainer *container = [[SomeContainer alloc] init];
SomeObject *obj = [container pop]; // Warning: Initializing 'SomeObject *__strong' with and expression of incompatible type 'id<A>'

I know that typecasting will get rid of the warning, however, I don't understand why I need it. SomeObject must implement whatever is declared in protocol A. Is there something that I am missing? Any explanation would be greatly appreciated.

Это было полезно?

Решение

Probably this is because SomeObject is something more than just id<A>. It's like initialising an object of derived class with pointer to the base class. You can initialize an instance of id<A> with SomeObject but when you do it vice versa you're receiving a warning, which says :"Hey, buddy you've just assigned base to derived, i.e. something that is present in derived (SomeObject *) may be missed in base id<A>"

for example SomeObject may contain method foo which is not present in protocol A, but now after that assignment of yours if you send foo message to obj it may crash, because id<A> is not necessarily has this method. It can, if it's also an instance of SomeObject, but it can be anything, which NECESSARILY responds only to the methods declared in A.

I hope all this makes sense

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top