Using the NSObject protocol

December 7th, 2011

I sometimes see code where the delegate has a type of NSObject rather than id:

id<CustomDelegate> delegate;
NSObject<CustomDelegate> *delegate;

and when asked "why" I'm always told the same answer:

"So that when using the delegate I can use the performSelector method"

This has always seemed odd to me, as when I am using the UITextfield delegate I can use performSelector even through that delegate is of type id.

Some investigation of how these two types of delegates worked lead me to the answer why one delegate using id gives me access to performSelector but the other does not. If we look at UITextDelegate and the CustomDelegate we can see a subtle difference between them:

@protocol UITextFieldDelegate <NSObject>
@protocol CustomDelegate

The UITextFieldDelegate is itself conforming to another protocol NSObject where as CustomDelegate is not. It is inside the NSObject protocol that performSelector is declared (along with other methods) rather than the NSObject class (NSObject class itself conforms to the NSObject protocol). Now because you don't get a compile time warning or runtime error by not conforming to NSObject in your delegate it is very easy to miss.

What do you think? Let me know by getting in touch on Twitter - @wibosco