我有一个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
最后一个示例导致编译器吐出此错误:
错误:'自我'未声明(首次使用此功能)
两个问题。为什么C函数看不到“自”变量,即使它在“自”对象内部,如何在不引起错误的情况下调用它?非常感谢任何帮助! :)
答案 0 :(得分:49)
为了使其起作用,您应该像这样定义C方法:
void cMethod(id param);
当你打电话时,请这样称呼:
cMethod(self);
然后,你可以写:
[param objcMethod];
在cMethod
。
这是因为self
变量是一个自动传递给Objective-C方法的特殊参数。由于C方法不享有此权限,如果您想使用self
,则必须自己发送。
答案 1 :(得分:25)
我知道您的问题已经由Aviad回答,但只是为了添加信息,因为这不是无关的:
在我的情况下,我需要从C函数调用Objective-C方法,我没有调用自己(通过注册全局热键事件触发的Carbon Event函数),因此将self作为参数传递是不可能的。在这种特殊情况下,您可以这样做:
在您的实现中定义一个类变量:
id thisClass;
然后在init方法中,将其设置为self:
thisClass = self;
然后,您可以从类中的任何C函数调用Objective-C方法,而无需将self
作为参数传递给函数:
void cMethod([some parameters]) {
[thisClass thisIsAnObjCMethod];
}
答案 2 :(得分:10)
C函数不是“self
对象内部”。事实上,没有。
Objective-C方法有效地将self
作为隐式参数,并在幕后完成魔术。对于普通的C函数,它们不与任何类或对象相关联,并且没有调用魔法,因此没有self
。如果需要,您需要将其作为参数显式传递给C函数。
答案 3 :(得分:5)
说实话,没有C方法这样的东西。 C有功能。为了说明差异,请查看以下示例:
这是一个有效的C程序,它定义了一个类型和两个与它一起使用的函数:
#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在文本之前放置的所有垃圾。功能完全相同。所以,在C中,你可以使用某种类似的方法,但它们实际上只是包含指向结构的指针的函数。
我不认为这回答了您原来的问题,但它确实解决了您似乎遇到的一些术语问题。
答案 4 :(得分:2)
到目前为止给出的答案的另一个选择是使用Objective-C运行时提供的objc_msgSend()
函数。