如何从C方法调用Objective-C方法?

我有一个Obj-C对象,里面有一堆方法。 有时候一个方法需要调用同一个对象内的另一个方法。 我似乎无法弄清楚如何获得一个C方法来调用Obj-C方法…

WORKS:调用Obj-C方法的Obj-C方法:

[self objCMethod]; 

工作:调用C方法的Obj-C方法:

 cMethod(); 

不工作:调用Obj-C方法的C方法:

 [self objCMethod]; // <--- this does not work 

最后一个例子导致编译器吐出这个错误:

错误:“自我”未申报(首次使用此function)

两个问题。 为什么C函数不能看到“self”variables,即使它在“self”对象的内部,如何在不引起错误的情况下调用它? 非常感谢您的帮助! 🙂

为了这个工作,你应该像这样定义C方法:

 void cMethod(id param); 

当你打电话的时候,就像这样说:

 cMethod(self); 

那么,你将能够写:

 [param objcMethod]; 

在你的cMethod

这是因为selfvariables是一个自动传递给Objective-C方法的特殊参数。 由于C方法不享受这个特权,如果你想使用self你必须自己发送它。

请参阅编程指南的“ 方法实现”部分 。

我知道你的问题已经由Aviad回答了,但只是为了补充信息,因为这不是无关的:

在我的情况下,我需要从一个C函数调用一个Objective-C方法,我没有自己调用(一个由注册全局热键事件触发的Carbon事件函数),所以传递self作为参数是不可能的。 在这种情况下,你可以这样做:

在你的实现中定义一个类variables:

 id thisClass; 

然后在你的init方法中,将它设置为self:

 thisClass = self; 

然后,您可以从类中的任何C函数中调用Objective-C方法,而无需将self作为parameter passing给函数:

 void cMethod([some parameters]) { [thisClass thisIsAnObjCMethod]; } 

C函数不是“ self对象的内部”。 其实没有什么

Objective-C方法可以有效地将self看作一个隐含的论证,在引擎盖下完成魔法。 对于普通的C函数,它们不与任何类或对象关联,并且没有调用魔法,所以没有self 。 如果你需要它,你需要将它作为一个参数明确地传递给你的C函数。

为了完全真实,没有C方法这样的东西。 C有function。 为了说明不同之处,请看下面的例子:

这是一个工作的C程序,它定义了一个types和两个函数:

 #include <stdio.h> typedef struct foo_t { int age; char *name; } Foo; void multiply_age_by_factor(int factor, Foo *f) { f->age = f->age * factor; } void print_foo_description(Foo f) { printf("age: %i, name: %s\n", f.age, f.name); } int main() { Foo jon; jon.age = 17; jon.name = "Jon Sterling"; print_foo_description(jon); multiply_age_by_factor(2, &jon); print_foo_description(jon); return 0; } 

这是该程序的一个Objective-C实现:

 #import <Foundation/Foundation.h> @interface Foo : NSObject { NSUInteger age; NSString *name; } @property (nonatomic, readwrite) NSUInteger age; @property (nonatomic, copy) NSString *name; - (void)multiplyAgeByFactor:(NSUInteger)factor; - (NSString *)description; - (void)logDescription; @end @implementation Foo @synthesize age; @synthesize name; - (void)multiplyAgeByFactor:(NSUInteger)factor { [self setAge:([self age] * factor)]; } - (NSString *)description { return [NSString stringWithFormat:@"age: %i, name: %@\n", [self age], [self name]]; } - (void)logDescription { NSLog(@"%@",[self description]); } @end int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Foo *jon = [[[Foo alloc] init] autorelease]; [jon setAge:17]; [jon setName:@"Jon Sterling"]; [jon logDescription]; [jon multiplyAgeByFactor:2]; [jon logDescription]; [pool drain]; return 0; } 

纯C程序的输出是:

 age: 17, name: Jon Sterling age: 34, name: Jon Sterling 

Objective-C程序的输出是:

 2009-08-25 17:40:52.818 test[8963:613] age: 17, name: Jon Sterling 2009-08-25 17:40:52.828 test[8963:613] age: 34, name: Jon Sterling 

唯一的区别是NSLog在文本之前放置的所有垃圾。 function完全一样。 所以,在C中,可以使用类似于方法的东西,但它们实际上只是包含指向结构体的指针的函数。

我不认为这回答了你原来的问题,但它确实清楚了你似乎已经有的术语问题。

到目前为止给出的答案的另一种select是使用Objective-C运行时提供的objc_msgSend()函数。