如何从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
。
这是因为self
variables是一个自动传递给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()
函数。