Alex Rivera | Logout

Defining categories for protocols in Objective-C?

Asked 2009-10-05T17:10:31.097
41

In Objective-C, I can add methods to existing classes with a category, e.g.

@interface NSString (MyCategory)
- (BOOL) startsWith: (NSString*) prefix;
@end

Is it also possible to do this with protocols, i.e. if there was a NSString protocol, something like:

@interface <NSString> (MyCategory)
- (BOOL) startsWith: (NSString*) prefix;
@end

I want to do this since I have several extensions to NSObject (the class), using only public NSObject methods, and I want those extensions also to work with objects implementing the protocol .

To give a further example, what if I want to write a method logDescription that prints an object's description to the log:

- (void) logDescription {
    NSLog(@"%@", [self description]);
}

I can of course add this method to NSObject, but there are other classes that do not inherit from NSObject, where I'd also like to have this method, e.g. NSProxy. Since the method only uses public members of protocol , it would be best to add it to the protocol.

Edit: Java 8 now has this with "virtual extension methods" in interfaces: http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v4.pdf. This is exactly what I would like to do in Objective-C. I did not see this question earning this much attention...

Regards, Jochen

Edit
Report

1 Answer

7

It isn't really meaningful to do so since a protocol can't actually implement the method. A protocol is a way of declaring that you support some methods. Adding a method to this list outside the protocol means that all "conforming" classes accidentally declare the new method even though they don't implement it. If some class implemented the NSObject protocol but did not descend from NSObject, and then you added a method to the protocol, that would break the class's conformance.

You can, however, create a new protocol that includes the old one with a declaration like @protocol SpecialObject <NSObject>.

answered 2009-10-05T17:33:27.150

Your Answer