I have the following method:
-(void)SomeMethod:(id)classOrProtocol;
It will be called like this:
[self someMethod:@protocol(SomeProtocol)];
Or
[self someMethod:[SomeClass class]];
Within the method body I need to decide if |classOrProtocol| is:
Any Class(Class) OR Any Protocol(Protocol) OR Anything else
[[classOrProtocol class] isKindOfClass: [Protocol class]]
Results in a (build)error:
Receiver ‘Protocol’ is a forward class and corresponding @interface may not exist
So how can I tell a Protocol from a Class from anything else?
In Objective-C 2 (i.e. unless you use 32 bit runtime on OS X)
Protocolis defined to be just a forward class, see/usr/include/objc/runtime.h. The real interface is nowhere declared. You can try to include/usr/inlcude/objc/Protocol.hby sayingbut as is written there, no method is publicly supported for an instance of
Protocol. The only accepted way to deal withProtocolinstances is to use runtime functions, given in Objective-C Runtime Reference. It’s not even publicly defined whetherProtocolis a subclass of anything, and it’s not even stated that it implementsNSObjectprotocol. So you can’t call any method on it.Of course you can use the source code of the runtime to see what’s going on.
Protocolinherits fromObject(which is a remnant from pre-OpenStep NeXTSTep), not fromNSObject. So you can’t use the familiar methods forNSObject-derived objects, includingClassofNSObject-derived objects. See the opensourced implementations of Protocol.h and Protocol.m. As you see there, the classProtocolitself doesn’t do anything, because every method just castsselftoprotocol_tand calls a function. In fact, as can be seen from the function_read_imagesand others inobjc-runtime-new.mm, theisapointer of aProtocolobject is set by hand when the executable and libraries are loaded, and never used.So, don’t try to inspect whether an
idis aProtocolor not.If you really need to do this, you can use
But, seriously, don’t do it.