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
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.
Any chance your protocol declaration includes the NSObject
protocol? Like this:
@protocol SomeDelegate <NSObject>
...
That's where the warnings are coming from because now your category does not implement the full protocol. In the test code I just typed up, removing NSObject
from the protocol removes the compiler warnings.
If you want the compiler to shut up about sending <NSObject> messages (and its important that you remember that thats the protocol name, not the class name) then just use 'id' variables, not 'id' since thats you explicitly telling the compiler "This is an object which only implements the SomeDelegate protocol".
Alternately, use NSObject as your variable type instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With