7

For object instances we can have their class declare some protocol conformance as in:

@protocol P <NSObject>
- (void) someMethod ;
@end

@interface C : NSObject <P>
@end

@implementation C
- (void) someMethod {

}
@end

But what about classes?

I find myself in this situation:

...
Class c = [self modelClass:kind] ;
if (c) {
    model = [c performSelector: @selector(decode:) 
                    withObject: [SExpIO read: [fm contentsAtPath:target]]] ;
}

and I wish there were a way for me to declare that there is such a thing as protocols for class methods.

In the above example, all classes that c can be a class-instance (Hmmm??) of, declare

+ (id) decode: (SExp *) root ;

Is there a way that I could transform the above into:

if (c) {
    model = [c decode: [SExpIO read: [fm contentsAtPath:target]]]
}

by using a suitable "class protocol" declaration?

verec
  • 5,224
  • 5
  • 33
  • 40

2 Answers2

9

A protocol is just a list of method declarations. They can be class methods or instance methods. Example:

@protocol MyProtocol

+ (id) aClassMethod;
+ (void) someOtherClassMethod;
- (void) someInstanceMethod;

@end
NSResponder
  • 16,861
  • 7
  • 32
  • 46
  • Didn't know you could do that... neat. – Steve Feb 22 '12 at 00:28
  • Wow! I didn't expect that! Thanks!! I tried and it even compiles, but I'm puzzled: given that Class c = [self modelClass:kind] ; really is a roundabout way of saying Class c = NSClassFromString(@"SomeClassThatIndeedImplementsModel") ; how come that this compiles at all: if (c) { model = [c decode: [SExpIO read: [fm contentsAtPath:target]]] ; } "Class" by itself doesn't have any type information, it seems? – verec Feb 22 '12 at 00:34
  • Classes are objects in Objective-C. Classes have meta-classes, which are also objects: `typedef struct objc_class *Class; typedef struct objc_object { Class isa; } *id; ` – Jack Lawrence Apr 09 '12 at 16:49
  • 1
    +1 Annoying that the Apple "The Objective-C Programming Language" reference doesn't mention this anywhere, nor does it include a single class method in its many code snippets – Rhubarb Nov 02 '12 at 13:32
7

There are such things as Protocols for class methods, and they're called.... Protocols. For example, it looks like you want a protocol that looks like this:

@protocol MyDecoder
+ (id)decode:(SExp *)root;
@end

You can then use it like this:

Class c = [self modelClass:kind];
if ([c conformsToProtocol:@protocol(MyDecoder)]) {
     model = [c decode: [SExpIO read: [fm contentsAtPath:target]]];
}
Matt Wilding
  • 20,115
  • 3
  • 67
  • 95