Ordinarily, when you declare an object as id
it counts an an "any" object (meaning that Objective-C will let you invoke any method from any class or protocol on the id
without warning).
However, when you declare an object as id<SomeProtocol>
, the meaning changes. In this case, you are instead saying: I will only invoke SomeProtocol
methods on this object.
The method:
- (void)release;
is declared in the NSObject
protocol but you have explicitly stated: I will only invoke MyProtocol
methods. So the compiler gives you a warning to tell you that you've broken your own promise.
Therefore, instead of:
id<MyProtocol> reference;
you should actually declare:
id<MyProtocol, NSObject> reference;
or:
NSObject<MyProtocol> reference;
since NSObject
(the class) implements NSObject
(the protocol).
or:
id reference;
which is the broadest of the lot: let me invoke anything on this object and never complain.
You can also (as Barry Wark suggested) have MyProtocol
include the NSObject
protocol -- although from a design perspective, you normally only do this if implementing MyProtocol
necessarily means using NSObject
. Normally, we only do this if NSObject
and MyProtocol
are linked heritarily or semantically.
A little information about the NSObject
protocol:
Everything you invoke retain/release/autorelease upon must implement this protocol. As you can infer from this: basically everything implements the NSObject
protocol (even though a few things don't descend from the NSObject
base class).
Another quick clarification: NSObject
(the class) and NSObject
(the protocol) are not reimplementations of the same API. They are split as follows:
NSObject (protocol) implements everything required to handle/inspect an existing object in a generic sense (retain/release, isEqual, class, respondsToSelector: etc).
NSObject (class) implements less generic methods: construction/destruction, thread integration, scripting integration.
So in most senses, the protocol is the more important of the two. Remeber that the class includes the protocol so if you descend from NSObject, you get both.