views:

72

answers:

3

Hi all,

In my application, I need to return the "Class" as a return type like:

Application.m:

+ (Class)getParserClass {
  return [NCCurrencyParser class];
}

NCCurrencyParser.m:

@interface NCCurrencyParser NSObject <NCParser>
@protocol NCParser
  +(NSNumber *)parserNumber:(NSNumber *)number;

in the caller method:

Class parserClass = [Application getParserClass];
[parserClass parserNumber:1.0];

But then the compiler gives me the error that parserClass may not respond to parseNumber. How can I force the Class have to adopt to some protocol like : Class <NCParser> (but it doesn't work)

+1  A: 

What the hell...this just seems VERY wrong.

But doing Class<NCParser> parserClass = [Application getParserClass]; should work

Joshua Weinberg
This will not work. `conformToProtocol:` method just works for an `NCObject` or `id` object, not for `Class` object.
Thanh-Cong Vo
Actually, any `Class` can be cast to id.
Jonathan Sterling
"any Class can be cast to id" really? Did you check?
Thanh-Cong Vo
This all screams of an underlying design issue anyway. What are you actually trying to do?
Joshua Weinberg
A: 

"But then the compiler gives me the error that parserClass may not respond to parseNumber"

If you just need to ignore the error message. Put this in the class which has the caller method:

#import "NCParser.h"

will solve your problem. It just works!

I think XCode bases on your import to determine the methods for Class.

"How can I force the Class have to adopt to some protocol like : Class"

You can check a NCObject or id conform to a protocol at compile time using id <AProtocol>. But I don't think you can do that for a Class object.

My approach is check it in runtime. Like this:

NSObject *object = [[class alloc] init];
NSAssert ([object conformsToProtocol:@protocol(AProtocol)], 
          @"`class` should conform AProtocol");
Thanh-Cong Vo
**"you just need to ignore the error message"**. "We must be very careful when we give advice to younger people: sometimes they follow it!" **Edsger W Dijkstra:**
Akusete
+2  A: 

Class objects in Objective-C are first class objects, and can can implement protocols like any other Objective-C object (id, NSObject*, ...)

So just do whatever you would normally do for any other Object protocol, ie:

+ (Class<NCParser>)getParserClass {
  return [NCCurrencyParser class];
}

And

Class<NCParser> parserClass = [Application getParserClass];
[parserClass parserNumber:1.0];

Build/Compiled/Tested on xcode 3.2.3, iPhone Simulator 4.0, GCC 4.2

Akusete
Hey look! its just what i said to do :)
Joshua Weinberg
I didn't mean to take credit for your good answer (+1), but since it seemed to be in dispute, I though it best to actually see what the actual behavior was.
Akusete
No, just screwin around, thanks for actually testing it. (+1)
Joshua Weinberg
Oh men, something was wrong with my code. The last time I tried it, it didn't work.
vodkhang