41

Suppose I have Objective C interface SomeClass which has a class method called someMethod:

@interface SomeClass : NSObject {
}

+ (id)someMethod;
@end

In some other interface I want to have a helper method that would dynamically invoke someMethod on a class like this:

[someOtherObject invokeSelector:@selector(someMethod) forClass:[SomeClass class];

What should be the implementation for invokeSelector? Is it possible at all?

- (void)invokeSelector:(SEL)aSelector forClass:(Class)aClass {
   // ???
}
2
  • 1
    In your example code you are declaring SomeClass as a root class. There should incredibly rarely be a need for this. Is it just a mistake in your question? Commented Nov 23, 2009 at 11:45
  • 1
    Yes. It is a mistake. Thanks for pointing that out. Commented Nov 23, 2009 at 17:59

4 Answers 4

84

Instead of:

[someOtherObject invokeSelector:@selector(someMethod) forClass:[SomeClass class];

call:

[[SomeClass class] performSelector:@selector(someMethod)];

Example (using GNUstep ...)

file A.h

#import <Foundation/Foundation.h>
@interface A : NSObject {}

- (NSString *)description;
+ (NSString *)action;
@end

file A.m

#import <Foundation/Foundation.h>
#import "A.h"

@implementation A

- (NSString *)description
{
    return [NSString stringWithString: @"A"];
}

+ (NSString *)action
{
    return [NSString stringWithString:@"A::action"];
}

@end

Somewhere else:

A *a = [[A class] performSelector:@selector(action)];
NSLog(@"%@",a);

Output:

2009-11-22 23:32:41.974 abc[3200] A::action

nice explanation from http://www.cocoabuilder.com/archive/cocoa/197631-how-do-classes-respond-to-performselector.html:

"In Objective-C, a class object gets all the instance methods of the root class for its hierarchy. This means that every class object that descends from NSObject gets all of NSObject's instance methods - including performSelector:."

Sign up to request clarification or add additional context in comments.

7 Comments

I knew I could use performSelector on NSObject. However, I was confused because I thought the type Class didn't have performSelector method. I didn't bother to try.
Code Sense doesn't suggest performSelector for [SomeClass class] experssion.
I'm not in front of my Mac, so I tried on Linux with GNUStep and it works ... :)
His class doesn't implement NSObject.
you can just do [A performSelector:@selector(action)];
|
4

In Objective-C, classes are objects as well. The class objects are treated differently, however, as they can call the instance methods of their root class (NSObject or NSProxy in Cocoa).

So it's possible to use all the instance methods defined in NSObject on class objects as well and the right way to dynamically invoke a class method is:

[aClass performSelector:@selector(aSelector)];

The apple docs are a bit more specific.

Comments

2

You shouldn't implement this yourself.

The NSObject Protocol has a performSelector: method that does exactly this.

10 Comments

Type Class is not NSObject. It doesn't have performSelector method
@Ben S: He's trying to invoke a class method. Class objects don't descend from NSObject.
In Objective-C classes are objects, direct subclasses of NSObject. Every instance method defined on NSObject will work on a class.
@Mike: Yes, but a Class object doesn't descend from NSObject.
@mipadi: Class is not a class, but a generic type for pointers to class objects. Each class object is an instance of its meta-class, which follows an inheritance chain that ultimately ends in the root class of the class in question, which is in this case NSObject. So yet, it descends from NSObject.
|
2

Is this built-in method what you want?

id objc_msgSend(id theReceiver, SEL theSelector, ...)

(See the runtime reference docs for this function.)

4 Comments

From your link: "This reference is useful primarily for developing bridge layers between Objective-C and other languages, or for low-level debugging. You typically do not need to use the Objective-C runtime library directly when programming in Objective-C."
But isn't avoiding built-in checks and balances the whole point of dynamically sending messages?
Never mind; didn't notice that it wasn't a subclass of NSObject.
I think this is the best option then.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.