views:

42

answers:

2

Hi,
I want to create a plug-in system using objective-c. I am getting list of all classes in the main bundle and checking for classes derived from plug-in base.

 int count = objc_getClassList(NULL, 0);  
 Class * buffer = (Class *)malloc(sizeof(Class) * count);  
 objc_getClassList(buf, count);

 NSMutableArray * classNameArray = [NSMutableArray array];

 for (int i = 0; i < count; i++) 
 {



  [buf[i] isDerivedFromClass:[PluginBase class]]; //<<< I need this
  NSString * classname=NSStringFromClass(buf[i]);

  [classNameArray  addObject:classname]; 

 }

Is there any equivalent method for that?

+3  A: 

Use

BOOL b = [yourObject isKindOfClass:[PluginBase class]];

You can use isMemberOfClass: to get exact class match.

Edit: For class objects, use the static (BOOL)isSubclassOfClass:(Class)aClass method:

BOOL b = [yourClassObject isSubclassOfClass:[PluginBase class]];
Eiko
I guess isKindOfClass works only if the receiver is a object and not plain CLASS.
shakthi
Oops, sorry, looked like "normal" objects. Edited the answer with the solution.
Eiko
Hey, Thanks for the answer. I tried with `if ([aClass isSubclassOfClass:[PluginBase class]])`, But still it failed with some of classes saying "class 'Object' does not implement doesNotRecognizeSelector: -- abort". I guess thier may be some classes in the list that are not dervied from NSOBject. I go to Graham Lee soln
shakthi
+1  A: 

While you can use isKindOfClass: to do exactly the kind of checking you describe, are you sure this is what you need? A bundle can declare any class as its principle class, and if that class supplies the same methods as your plugin base class then it can be used as such (this is Objective-C's duck typing). Therefore you could be testing, rather than for subclasses, for existence of the plugin's API methods.

It also looks like you've missed out on using the principle class. Looking at the documentation, a bundle can declare in its Info.plist file a class that represents the entry point to that bundle's functionality. Rather than searching through every class looking for something compatible with your API, you can just require that plug-in authors register a compatible principle class. This approach allows plug-in authors to declare multiple conforming classes for using patterns like Strategy, State or Decorator while still exposing a single entry point. Your approach described in your question would try to use all of those instances concurrently.

Graham Lee
OK. Forget about plug-in. I am trying to get list of all classes in the main bundle that is derived from some specific class. I guess isKindOfClass works only if the receiver is a object and not plain CLASS.
shakthi
@shakthi: you can use `[MyClass isSubclassOfClass: [InterestingClass class]]`
Graham Lee
@ Graham Lee: You should make that comment an answer because it is the correct answer to the question asked.
JeremyP
@JeremyP: it is, but only because I believe the question being asked is the wrong one :)
Graham Lee
Ok. I changed the approach. I am using protocols now. `if (class_conformsToProtocol(aClass, @protocol(PluginProtocal)))`. works for me .
shakthi