This is an objective-c question.
I would like to call a method in an object, but there is no instantiation of the object. Is this possible?
The method I want to call is not a class method.
This is an objective-c question.
I would like to call a method in an object, but there is no instantiation of the object. Is this possible?
The method I want to call is not a class method.
Unless the method is static
you will not be able to do this. static
routines in Objective-C will be prepended with a +
. For example NSObject provides these two routines (among many):
+ (id)alloc; // static - an NSObject instance is not required
- (NSString*)description; // nonstatic - an NSObject instance is required
One would make the respective calls like so:
NSObject* result = [NSObject alloc];
NSString* desc = [result description];
You can't call a method on an object that doesn't exist. But you can call a method on a class even if you have no instantiated objects of that class. (That's what alloc is in @fbrereton's answer -- a class method).
Class methods are declared and defined with a + instead of a -, are called on the class rather than the instance, and cannot access self or any instance variables in the class (for reasons that should be obvious).
You can indeed invoke an instance method without an instance, provided it is functionally a class method (that is, it accesses no instance variables). Here's an example:
/*
Compile with:
gcc -framework Foundation inst_method_without_inst.m -o inst_method_without_inst
*/
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Foo : NSObject {
}
- (BOOL)doSomethingWithThis:(NSString *)this;
@end
@implementation Foo
- (BOOL)doSomethingWithThis:(NSString *)this {
NSLog(@"Look, it's this: %@", this);
return YES;
}
@end
typedef BOOL (*my_sel_t)(id, SEL, NSString *);
int
main(void) {
Class cls = [Foo class];
SEL my_sel = @selector(doSomethingWithThis:);
Method m = class_getInstanceMethod(cls, my_sel);
// You could also use +[NSObject instanceMethodForSelector:] to get |m|,
// since |cls| is a kind of NSObject.
my_sel_t f = (my_sel_t)method_getImplementation(m);
BOOL result = f(nil, my_sel, @"Hello from an instanceless instance method invocation!");
NSLog(@"result: %d", (int)result);
return EXIT_SUCCESS;
}
You could get it to work even if the instance method accesses instance variables by allocating memory for it to work with (using either +alloc
or class_getInstanceSize()
plus malloc()
) and passing a pointer to that memory as the first id
argument to the implementation instead of nil
.
While this is entertaining as an exercise, I can't think of a good reason to not just instantiate the class and use the standard messaging syntax and compiler support. In fact, the only reason we couldn't just do [(Foo *)nil doSomethingWithThis:@"BOO!"]
here is that objc_msgSend()
special-cases messages to nil
with the result that NO
is returned and nothing happens.
Perhaps you just want a plain-old C function. If you don't want a class method, and you don't want an instance method, that appears to be your only option. Don't be afraid of using C functions in Objective-C. Every technique has its place.
Sorry to nit-pick Chris' terminology, but we don't call a method on an object in Objective-C, we send a message to an object. When you send a message, the runtime will look up the appropriate method and call it. The distinction matters.