您在Objective-C中可以用C做什么?

时间:2010-06-14 14:42:38

标签: objective-c c compare

你可以在Objective-C中用C(C99标准)做什么? (如果你愿意,请附上代码示例)

4 个答案:

答案 0 :(得分:9)

我会有点冒昧,不同意其他人。虽然技术上确实在一种语言中可能存在的任何一种语言都可能(其中“可能”意味着“可计算”),但它们在表达自然容易的内容方面存在差异。计算机可能会对你用C语言编写的代码做同样的事情,但是正在编写截然不同的代码来使它做这些事情。

正如其他人所说,Objective-C提供了一个用C编写的完整运行时库,它允许您创建Objective-C数据结构并调用C函数,但执行它的代码将非常冗长,相当迂回且完全势在必行。在Objective-C中,代码更具说明性,更简洁,更易读。

通常,尝试在C中编写Objective-C事物只会使您的代码比使用任何一种语言更糟糕。例如,这是一个用Objective-C编写的简单程序:

@interface NumberAdder : NSObject {
    int storedValue;
}

- (id)initWithStoredValue:(int)value;
- (int)resultOfAddingStoredValue:(int)numberToAdd;
@end

@implementation NumberAdder
- (int)resultOfAddingStoredValue:(int)numberToAdd {
    return numberToAdd + storedValue;
}

- (id)initWithStoredValue:(int)value {
    if (!(self = [super init])) return nil;
    storedValue = value;
    return self;
}
@end

int main() {
    id adder = [[NumberAdder alloc] initWithStoredValue:4];
    int result = [adder resultOfAddingStoredValue:3];
    printf("It is %d\n", result);
    return 0;
}

这是用C语言编写的与Objective-C运行时相同的东西(未经过测试,但应该大致正确):

int returnPlusStoredValueImp(id self, SEL _cmd, int arg) {
    int *storedValue = nil;
    object_getInstanceVariable(self, "storedValue", &storedValue)
    return arg + *storedValue;
}

id numberAdderInit(id self, SEL _cmd, int valueToStore) {
    objc_super superInfo = {self, objc_lookupClass("NSObject")};
    self = objc_msgSendSuper(super_info, sel_getName("init"));
    if (!self) return nil;
    object_setInstanceVariable(self, "storedValue", &valueToStore);
    return self;
}

void createNumberAdderClass() __attribute(constructor)__ {
    Class NumberAdder = objc_allocateClassPair(objc_lookupClass("NSObject"), "NumberAdder", 0);
    if (!NumberAdder) return;
    class_addIvar(NumberAdder, "storedValue", sizeof(int), 4, "i"); // I'm actually not sure if the fourth argument is correct, so it's probably wrong, but just take that as a sign of how much this way of coding sucks
    objc_registerClassPair(NumberAdder);
    SEL nameOfPlusStoredValue = sel_registerName("resultOfAddingStoredValue:");
    SEL nameOfInit = sel_registerName("initWithStoredValue:");
    class_addMethod(NumberAdder, nameOfPlusStoredValue, returnPlusStoredValueImp, "i@:i");
    class_addMethod(NumberAdder, nameOfInit, numberAdderInit, "@@:i");
}

int main() {
    id adder = objc_msgSend(objc_lookupClass("NumberAdder"), sel_getName"alloc");
    adder = objc_msgSend(adder, sel_getName("initWithStoredValue:"), 4);
    int result = (int)objc_msgSend(adder, sel_getName("resultOfAddingStoredValue:"), 3);
    printf("It is %d\n", result);
    return 0;
}

答案 1 :(得分:8)

绝对没有。 Objective-C的OO功能是作为用C编写的小型运行时库实现的。

虽然有些评论者可能会指出Objective-C有块而C没有,这实际上是Objective-C使用的 C 的GCC / LLVM扩展,但它不是ObjC功能

答案 2 :(得分:3)

正如格雷厄姆所说 - 在Objective-C中绝对没有任何东西可以在C中完成。当然,在C中也没有任何东西可以做到,不可能在集会中完成。这只是打字的问题。

(我希望大会提到的内容足以表明,不,我并没有远程建议在纯C中编写OO模式远远不是一件很有效的事情......)

还有一些其他兴趣点:

  • Objective-C最初是一个预处理器,它将Objective-C代码转换为可由标准C编译器编译的C代码。也就是说,Objective-C最初从未直接编译,而是转换为直接C,然后编译。

  • Objective-C对象可以被认为是C结构,其中结构中的第一个条目 - isa - 始终是指向元数据的指针 - Class - - 描述结构/实例。

  • 块是C的扩展,现在被提议作为WG-14(C标准委员会)中C语言的补充。由Apple实现的块绝对不会 需要可执行堆栈。这是他们设计中的一项艰难要求。

  • LLVM有一个实际上可以将Objective-C重写为C的重写器,并且显然已用于在Xbox 360游戏中启用Objective-C编码(参见http://permalink.gmane.org/gmane.comp.compilers.llvm.devel/31996)。

    < / LI>

答案 3 :(得分:1)

没有这样的事情。通常,您可以使用任何编程语言编写任何内容。