I’m quite a newbie in Objective C, though I have some background in Java reflection.
Here, I have a classic class method findAll that find all the domain objects from the database. The class Univers directly inherits from DomainObject
@interface DomainObject : NSObject
- (NSString *) execute : (NSString*) method withJson:(NSString*)json;
+ (NSString*)findAll: (NSString*)json;
@end
@implementation DomainObject
- (NSString *) execute: (NSString*) method withJson:(NSString*)json{
method = [NSString stringWithFormat:@"%@%@", method, @":"];
//method is 'findAll:'
NSString* result = [ self performSelector:
NSSelectorFromString(method) withObject:json];// Error here
return result;
}
@end
The code was working when findAll was NOT a class method (ie -findAll declaration), but now I have the error : NSInvalidArgumentException -[Univers findAll:]
It clearly seems that the runtime is looking for an instance method.
Any idea to find my class method ?
Instead of calling
you need to call
for class methods.
After all it’s the object instance’s class that supposed to be calling the method, not the instance itself.
Short explanation:
NSObjectimplements- (Class)class;(not to be mistaken with+ (Class)classof similar effect, whichNSObjectimplements, too!) which returns the Class object of your instance object. Keep in mind that in Objective-C in addition to plain instance objects, Classes are actual objects, too: objects of typeClass, that is (vs.id,NSObject, …).See the documentation for the
-classmethod here.Btw, you should probably wrap your method call into an conditional block to prevent exceptions caused by calls to missing methods.
In general it’s a common pattern in Objective-C to call an object’s class method by receiving the class object via
[object class].Consider this case of a class called
Fooimplementing a convenience method for returning an autporeleased instance of itself (to be called via:Foo *newFoo = [Foo foo];):While it would certainly be possible to implement said method like this (after all we know the object’s class name, right?):
the correct way is this:
As the first one would cause problems with polymorphism in subclasses (Such as a subclass called
FooBar, for which it should clearly be[FooBar alloc] …, not[Foo alloc] …. Luckily[[self class] alloc]solves this dynamically).While this is clearly not the right place for a thorough explanation of this (rather offtopic one might say) it’s certainly worth noting/warning about, imho.