2010-06-14 8 views

Antwort

9

Ich werde ein wenig anmaßend sein und mit allen anderen nicht einverstanden sein. Während es technisch wahr ist, dass alles Mögliche in einer Sprache in einem anderen möglich ist (wo "möglich" bedeutet "berechenbar"), unterscheiden sie sich in natürlich und leicht. Der Computer macht vielleicht die gleiche Sache als Antwort auf den Code, den Sie in C schreiben, aber Sie schreiben radikal unterschiedlichen Code, um es diese Dinge zu tun. Wie andere bereits sagten, bietet Objective-C eine vollständige Laufzeitbibliothek, die in C geschrieben ist und Ihnen erlaubt, Objective-C-Datenstrukturen zu erstellen und C-Funktionen aufzurufen, aber der Code dafür ist sehr ausführlich, ziemlich umständlich und absolut geboten. In Objective-C ist der Code deklarativer, prägnanter und viel besser lesbar.

Im Allgemeinen wird der Versuch, Objective-C-Dinge in C zu schreiben, nur Ihren Code schlechter machen, als wenn Sie beide Sprachen idiomatisch verwenden würden.Zum Beispiel, hier ist ein einfaches Programm in Objective-C geschrieben:

@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; 
} 

Und hier ist die gleiche Sache in C geschrieben, mit der Objective-C-Laufzeit (nicht getestet, sollte aber in etwa richtig sein):

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, "[email protected]: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

+1 für die harte Linie und demonstrieren es. Gute Antwort. – bbum

+0

virtuell +2, da der ganze Punkt um Computersprachen herum ist (oder um), da wir ansonsten alle noch Assembly verwenden würden, da keine Notwendigkeit für höhere "linguistische Strukturen" entstehen würde. – ShinTakezou

1

Es gibt so etwas nicht. Im Allgemeinen können Sie alles in einer beliebigen Programmiersprache programmieren.

+5

Solange "irgendetwas" viele Dinge auslässt. – danben

+1

Fantastisch, kannst du bitte deine Lösung zum Halteproblem posten. http://en.wikipedia.org/wiki/Halting_problem – JeremyP

+0

wirklich Sjoerd? Ich denke, wir brauchen nur eine Programmiersprache!/Sarkasmus – Jage

8

Absolut nichts. Objective-C OO-Features werden als kleine Laufzeitbibliothek geschrieben in C implementiert

Während einige Kommentatoren weisen darauf hin, könnten, dass Objective-C-Blöcke hat und C nicht den Fall, das ist eigentlich eine GCC/LLVM Erweiterung C dass Objective-C nutzt es, es ist keine ObjC-Funktion.

+2

Eine Eigenschaft, die es oft wert ist, die Verwendung von zu vermeiden, da es manchmal einen ausführbaren Stapel benötigt (gcc erzeugt ein Trampolin auf dem Stapel, um den Stapelrahmen wiederherzustellen, so dass die Verschachtelung funktioniert, ist ein Trampolin eine kleine Funktion, die etwas Magie macht: P) Ein ausführbarer Stapel ist möglicherweise nicht verfügbar ... zum Beispiel mit NX eingeschaltet (gcc verwendet wahrscheinlich madvise oder etwas, damit es noch funktioniert ... vielleicht) – Spudd86

+2

Um Grahams gut gemachte Punkte hinzuzufügen, wird die kleine Laufzeitbibliothek sogar als eine Reihe von C-Funktionen dargestellt, die Sie verwenden dürfen. Mit anderen Worten, Sie können sogar Objective-C-Bibliotheken verwenden, ohne Objective-C zu verwenden. Siehe hier: http://developer.apple.com/mac/library/documentation/cocoa/reference/objcruntimeref/Reference/reference.html – harms

+3

Blöcke - wie in Mac OS X implementiert - benötigen absolut keine ausführbare Datei * Stapel. Das war eine Anforderung in ihrem Design. – bbum

3

Wie Graham sagte - es gibt absolut nichts, was in Objective-C getan werden kann, was in C nicht möglich ist. Natürlich kann man in C auch nichts tun, was nicht möglich ist in der Montage durchgeführt werden. Es ist nur eine Frage des Tippens.

(Ich hatte gehofft, dass die die Versammlung zu erwähnen wäre genug, dass, um anzuzeigen, nein, ich bin nicht remote, dass das Schreiben OO-Muster in reinem C darauf hindeutet, ist der Ferne eine produktive Sache zu tun ...)

Es gibt ein paar weiteren Punkte von Interesse:

  • Objective-C begann als Prä-Prozessor, die Objective-C-Code in C-Code eingeschaltet, die von einem Standard-C-Compiler kompiliert werden. Das heißt, Objective-C wurde ursprünglich nie direkt kompiliert, sondern ins gerade C übersetzt und dann kompiliert.

  • Objective-C-Objekte können als C-Strukturen gedacht werden, wo der erste Eintrag in der Struktur - die isa - ist immer ein Zeiger auf die Metadaten - die Class -, die die Struktur/Instanz beschreibt.

  • Blöcke sind eine Erweiterung zu C, jetzt als Ergänzung zur C-Sprache in WG-14 vorgeschlagen (C-Normenausschuss). Blöcke, wie sie von Apple implementiert werden, benötigen nicht erfordern einen ausführbaren Stapel. Es war eine harte Anforderung in ihrem Design.

  • LLVM hat einen Rewriter, der eigentlich Objective-C in C umschreiben kann und anscheinend verwendet wurde, um Objective-C-Codierung in Xbox 360-Spielen zu ermöglichen (siehe http://permalink.gmane.org/gmane.comp.compilers.llvm.devel/31996).

+0

nicht eine Frage des Tippens nur. HL-Syntaxen und verschiedene Paradigmen helfen "anders zu denken" und verändern die Wahrnehmung eines Problems (und verändern so die Art, wie Sie die Lösung finden). Sie sind Werkzeuge und ohne sie kann man nicht dasselbe erreichen. Sie können nicht denken, dass es für den Bau einer Kathedrale ausreicht zu wissen, wie man Steine ​​über Ziegelsteine ​​legt und die gleichen Werkzeuge verwendet, die Sie zum Bau Ihres 1m hohen ersten Ziegelsteinhauses verwendet haben. Wenn Sie mit der Neueingabe beginnen, werden Sie feststellen bald wirst du die Werkzeuge, die du schon hattest, neu aufbauen/schreiben ... aber sobald du es tust, bestätigst du, dass du sie brauchst, um weiterzumachen.Zyklus – ShinTakezou

+0

@ShinTakezou Ich glaube, du und ich sind in gewaltsamer Übereinstimmung. Ich wollte nie implizieren, dass das Schreiben von OO-Code in geradem C eine vernünftige Lösung ist. – bbum

Verwandte Themen