Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective C : Given a Class id, can I check if this class implements a certain protocol? Or has a certain selector?

I want to use this for an object factory: Given a string, create a Class, and if this Class supports a protocol (with a Create() method) then alloc the class and call Create.

like image 728
Jacko Avatar asked Feb 26 '10 20:02

Jacko


People also ask

How do you make a class conform to a protocol in Objective C?

Objective-C Language Protocols Conforming to Protocols It is also possible for a class to conform to multiple protocols, by separating them with comma. Like when conforming to a single protocol, the class must implement each required method of each protocols, and each optional method you choose to implement.

What is respondstoselector in objective C?

Returns a Boolean value that indicates whether the receiver implements or inherits a method that can respond to a specified message. Required.

How do I find the class of an object in Objective C?

[yourObject isKindOfClass:[a class]] // Returns a Boolean value that indicates whether the receiver is an instance of // given class or an instance of any class that inherits from that class.


2 Answers

NSString *className; //assume this exists
Class class = NSClassFromString(className);
if ([class conformsToProtocol:@protocol(SomeProtocol)]) {
    id instance = [[class alloc] init];
    [instance create];
}
like image 104
Chuck Avatar answered Oct 03 '22 06:10

Chuck


Class klass = NSClassFromString(classname);
if ([klass instancesRespondToSelector:@selector(create)]) {
  [[klass alloc] create];
}

May I, however, point out just how many awful Objective-C rules you're breaking by doing the above? For example, you should never be calling methods on an allocated-but-not-initialized instance. The Xcode Static Analyzer will give you all sorts of warnings about memory leaks.

A better option would be this:

[[[klass alloc] init] create];

But you seem to imply that you don't want to call init.

You could consider a class method: [klass create], which would return a non-owned instance of klass. Then you'd just check [klass respondsToSelector:@selector(create)] before calling it.

like image 31
BJ Homer Avatar answered Oct 03 '22 06:10

BJ Homer