Regan
Regan

Reputation: 41

id myObj<MyProtocol> vs if( [obj class] conformsToProtocol:@protocol(MyProtocol) )

In Objective-C, which is the better way to code?

// Version #1

id obj<MyProtocol>;
[obj myMessage];

// Version #2

   id obj;
   if( [[obj class] conformsToProtocol:@protocol(MyProtocol)] )
       [obj myMessage];

For some reason I see Version one in example code but to me Version 2 seems more safe. What happens if obj is assigned from a generic id that does not conform to the protocol MyProtocol at run time?

Upvotes: 1

Views: 1329

Answers (3)

Hermann Klecker
Hermann Klecker

Reputation: 14068

As objective-c binds on runtime and is not type save, do both. The proper declaration prevents all errors that are detected on compile time. For good reasons most of them are just warnings. The runtime check prevents the app from crashing in the event that you dont get in a reference what you expect to deal with.

Upvotes: 1

bbum
bbum

Reputation: 162722

The first is a compile time check.

The second is a runtime check.

Isaac's answer of "do both" is certainly viable, but protocol conformance checks have had significant overhead in certain places at certain times (caveat; premature optimization and all that). As well, protocols do support @optional methods.

I would recommend using the compile time protocol check (i.e. declarative, precise, interfaces and use) along with respondsToSelector: at runtime. That'll make the transition to/from @optional / @required easier as the code is refactored and respondsToSelector: is really quite fast.

Upvotes: 9

Isaac
Isaac

Reputation: 10834

Do both:

id<MyProtocol> obj;
if( [[obj class] conformsToProtocol:@protocol(MyProtocol)] )
{
    [obj myMessage];
}

The first, the variable type, tells the compiler what you intend to do with the variable, but does not guarantee that the variable will actually hold what you want it to; the second, the conformance check, tests that the variable actually holds what you want it to.

Upvotes: 1

Related Questions