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