175

I have a Class (but no instance) and need to know if it conforms to a certain protocol. However, Class can be subclassed several times and class_conformsToProtocol() ignores protocols declared on superclasses.

I could just use class_getSuperclass() and recursively check all the classes in the hierarchy upwards until the superclass is nil. However I wonder if that might be inefficient for deeply nested class hierarchies, and maybe there's a nicer way to do that?

In other words, how is the NSObject method conformsToProtocol best implemented using Objective-C runtime methods so that it finds protocols on superclasses?

 [myObject conformsToProtocol:@protocol(MyProtocol)];

If I'm on the right track with recursively going up the class hierarchy just let me know.

CodeSmile
  • 64,284
  • 20
  • 132
  • 217

3 Answers3

312

According to the docs,

[MyClass conformsToProtocol:@protocol(MyProtocol)];

should work.

Pang
  • 9,564
  • 146
  • 81
  • 122
Wevah
  • 28,182
  • 7
  • 83
  • 72
  • 4
    You're right. It was late and no code completion suggestions were made by Xcode. I checked the definition of Class and seeing that it was "typedef struct objc_class *Class" I didn't check the NSObject class reference. – CodeSmile Aug 09 '10 at 07:25
  • Is there any way to do it on an instance instead of a class? My `self.delegate` implements multiple protocols and I want to check if it conforms to others than it's class. – Konrad Piascik Sep 17 '18 at 17:48
  • @KonradPiascik Just call it on the instance instead: `[someObject conformsToProtocol:@protocol(MyProtocol)]`. – Wevah Sep 17 '18 at 23:35
4

Or, in case it is a general pointer, like:

Class<MyProtocol> someClassPointer = nil;

you can use:

[someClassPointer.class conformsToProtocol:@protocol(MyProtocol)];
Nikita
  • 1,811
  • 1
  • 20
  • 41
0

check if class conforms to protocol?

Two Method

use conformsToProtocol

  • syntax
    • [someClassObj conformsToProtocol: objc_getProtocol("YourProtocolName")]
  • example
(lldb) po self
<AKAnisetteProvisioningService: 0x105f16870>

(lldb) po Protocol * $akaisdProto = objc_getProtocol("AKAppleIDSigningDaemonProtocol")
(lldb) po $akaisdProto
<Protocol: 0x1dc7d2e90>

(lldb) po [self conformsToProtocol: $akaisdProto]
0x0000000000000001

use class_conformsToProtocol

  • syntax
    • class_conformsToProtocol(NSClassFromString(@"YourClassName"), objc_getProtocol("YourProtocolName"))
  • example
(lldb) po Class $akapsClass = NSClassFromString(@"AKAnisetteProvisioningService")
(lldb) po $akapsClass
AKAnisetteProvisioningService

(lldb) po Protocol * $akaisdProto = objc_getProtocol("AKAppleIDSigningDaemonProtocol")
(lldb) po $akaisdProto
<Protocol: 0x1dc7d2e90>

(lldb) po class_conformsToProtocol($akapsClass, $akaisdProto)
0x0000000000000001
crifan
  • 12,947
  • 1
  • 71
  • 56