Can a category simultaneously implement a protocol?

Justin Searls picture Justin Searls · Nov 1, 2009 · Viewed 7.7k times · Source

If a category I'm creating for a class adds methods that also fulfill the contract set out by a protocol, I'd like to flag that category class as implementing the protocol, and thereby indicate to the Obj-C pre-processor that the class effectively implements the protocol as well.

Example delegate (for clarity, thanks Ole!):

@protocol SomeDelegate <NSObject>
  - (void)someDelegateMessage;
@end

Example category:

@interface NSObject (SomeCategory) <SomeDelegate>
  - (void)someDelegateMessage;    
@end

And with an otherwise typical implementation

@implement NSObject (SomeCategory)
  - (void)someDelegateMessage {}
@end

When I actually try this, I get a warning for each NSObject method:

warning: incomplete implementation of category 'SomeCategory'

warning: method definition for '-description' not found

...

warning: method definition for '-isEqual:' not found

warning: category 'SomeCategory' does not fully implement the 'NSObject' protocol

Works fine if I remove <SomeDelegate> from the declaration, but of course NSObject isn't recognized as a SomeDelegate

Answer

Jens Ayton picture Jens Ayton · Nov 1, 2009

A workaround is to declare the protocol on a category with no implementation, and implement the method in a different category, e.g.:

@interface NSObject (SomeCategory) <SomeDelegate>
  - (void)someDelegateMessage;    
@end

@implementation NSObject (SomeCategory_Impl)
  - (void)someDelegateMessage {}
@end

If you do this, NSObject will be considered to conform to <SomeDelegate> at compile time, and runtime checks for someDelegateMessage will succeed. However, conformsToProtocol: runtime checks will fail.

Of course, you should file a bug requesting that methods declared on the core class don’t generate warnings.