Я собираюсь быть немного самонадеянным и не соглашаться со всеми остальными. Хотя технически верно, что все возможное на одном языке возможно на другом (где «возможно» означает «вычислимый»), они отличаются тем, что вы можете выразить естественно и легко . Компьютер может делать то же самое в ответ на код, который вы пишете на C, но вы пишете совершенно другой код, чтобы заставить его делать эти вещи.
Как уже говорили другие, Objective-C предоставляет полную библиотеку времени выполнения, написанную на C, которая позволит вам создавать структуры данных Objective-C и вызывать функции C, но код для этого будет очень многословным, довольно окольным и полностью императив. В Objective-C код является более декларативным, более кратким и гораздо более читабельным.
В общем, попытка написать вещи в Objective-C на 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;
}