如何在没有实例化对象的情况下调用方法

时间:2009-09-03 23:16:34

标签: iphone objective-c cocoa

这是一个客观问题。

我想在对象中调用一个方法,但是没有对象的实例化。这可能吗?

我想调用的方法不是类方法。

5 个答案:

答案 0 :(得分:5)

您无法在不存在的对象上调用方法。但是,即使您没有该类的实例化对象,也可以在上调用方法。 (这就是在@ fbrereton的答案中的分配 - 一种类方法)。

使用+而不是a来声明和定义类方法,在类而不是实例上调用它们,并且不能访问类中的self或任何实例变量(原因应该是显而易见的)。

答案 1 :(得分:4)

除非方法为static,否则您将无法执行此操作。 Objective-C中的static例程将以+为前缀。例如,NSObject提供了这两个例程(在众多例程中):

+ (id)alloc; // static - an NSObject instance is not required
- (NSString*)description; // nonstatic - an NSObject instance is required

可以像这样进行各自的调用:

NSObject* result = [NSObject alloc];
NSString* desc = [result description];

答案 2 :(得分:2)

很抱歉挑选Chris的术语,但我们在Objective-C中没有调用对象上的方法,我们向对象发送消息。发送消息时,运行时将查找相应的方法并调用它。区别很重要。

答案 3 :(得分:1)

你确实可以在没有实例的情况下调用实例方法,前提是它在功能上是一个类方法(也就是说,它不访问任何实例变量)。这是一个例子:

/*
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;
}

即使实例方法通过为其使用分配内存(使用+allocclass_getInstanceSize()malloc())并传递指针来访问实例变量,也可以使其工作将该内存作为实现的第一个id参数而不是nil

虽然这很有趣,但我不能想到一个很好的理由不仅仅是实例化类并使用标准的消息传递语法和编译器支持。事实上,我们不能在[(Foo *)nil doSomethingWithThis:@"BOO!"]执行objc_msgSend()的唯一原因是nil特殊情况消息发送到NO,结果是返回{{1}}并且没有任何反应。

答案 4 :(得分:1)

也许你只想要一个普通的C函数。如果您不想要类方法,并且不需要实例方法,那么这似乎是您唯一的选择。不要害怕在Objective-C中使用C函数。每种技术都有它的位置。