Question

In Objective-C when you declare an instance variable you can check if it conforms to a protocol on assignment at compile time like so:

id <MyProtocol> variable;

Is it possible to check whether an object assigned to the variable conforms to two separate protocols at compile time? As in:

id <MyProtocol, MyOtherProtocol> variable;

I know I can do runtime checking using conformsToProtocol: and respondsToSelector et al, (which I do before actually using the object for added safety), and I could write my own setter method that does the check, but I'd like to know at compile time.

Was it helpful?

Solution

I think the best is to use your own code:

id <MyProtocol, MyOtherProtocol> variable;

And before calling a method, check if the variable responds to what you want to call:

if ([variable respondsToSelector:@selector(aMethod:)]) {
    [variable aMethod:nil];
}

Since Objective-C is a dynamic language, just declaring the variable protocol can't assure that it conforms to the protocol. It'll mostly generates warnings when you build.

OTHER TIPS

Yes, that syntax is correct.

The correct way to check if an object conforms to a protocol is to do this:

if ([myObj conformsToProtocol:@protocol(MyProtocol)]) {
  //conformance!
}

Note that this works as both an instance method and a class method.

If for some bizarre reason you can't use the conformsToProtocol:, you can drop down to the runtime level:

#import <objc/runtime.h>

Protocol * p = objc_getProtocol("MyProtocol");
if (class_conformsToProtocol([myObj class], p)) {
  //conformance!
}

You can’t always check protocol conformance in compile-time because an object of (non-qualified) type id is always a valid object from the compiler’s perspective. For instance,

id<P1> p1;
id<P2> p2;
id p0;

// compiler warning: assigning to 'id<P1>' from incompatible type 'id<P2>'
p1 = p2;

// no compiler warning
p0 = p2;
p1 = p0;

That being said, <P1, P2> will give you warnings in case the object doesn’t conform to both protocols if that can be known at compile-time:

id<P1> p1;
id<P2> p2;
id<P1, P2> p12;
id<P1, P2> q12;
id p0;

p12 = p1; // warning: assigning to 'id<P1,P2>' from incompatible type 'id<P1>'
p12 = p2; // warning: assigning to 'id<P1,P2>' from incompatible type 'id<P2>'
p12 = q12; // no compiler warning

// no compiler warning
p0 = p1;
p12 = p0;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top