2011-01-13 6 views
1

Für die Kompilierung mithilfe der Eigenschaftensyntax muss der Typ des Empfängers zur Kompilierungszeit bekannt sein. Ich verstehe vielleicht etwas nicht, aber das scheint eine kaputte oder unvollständige Compiler-Implementierung zu sein, wenn man bedenkt, dass Objective-C eine dynamische Sprache ist.Warum erfordern Eigenschaften explizite Typisierung während der Kompilierung?

@property (nonatomic, retain) NSString *comment; 

und mit synthetisiert:

"Dokument" ist ein Beispiel für eine von mehreren Klassen, die zu entsprechen:

Die Eigenschaft "Kommentar" wird mit definierten

@protocol DocumentComment <NSObject> 

@property (nonatomic, retain) NSString *comment; 

@end 

und wird einfach wie folgt deklariert:

id document; 

Wenn folgende Eigenschaftssyntax:

stringObject = document.comment;  

die folgenden Fehler von gcc erzeugt wird:

error: request for member 'comment' in something not a structure or union 

jedoch die folgende äquivalente empfänger Methode Syntax, kompiliert ohne Warnung oder Fehler und Funktioniert wie erwartet zur Laufzeit:

stringObject = [document comment]; 

Ich verstehe nicht, warum Eigenschaften erfordern, dass der Typ des Empfängers zur Kompilierzeit bekannt ist. Gibt es etwas, das mir fehlt? Ich benutze einfach die letztere Syntax, um den Fehler in Situationen zu vermeiden, in denen das empfangende Objekt einen dynamischen Typ hat. Eigenschaften scheinen halb gebacken.

Antwort

4

Zum Kompilieren des Eigenschaftszugriffs muss der Eigenschaftsname in den richtigen Getter/Setter-Namen übersetzt werden. Ohne den Typ des Empfängers zu kennen, kann der Compiler nicht wissen, was die Getter/Setter genannt wird, als die Eigenschaft den Namen als Teil seiner Erklärung außer Kraft gesetzt haben, etwa so:

@property (nonatomic, retain, getter=myComment) NSString *comment; 

Wenn der Compiler waren gehen Sie voran und erzeugen Sie Code für Ihr untypisiertes Beispiel, es würde [document comment] erzeugen, das zur Laufzeit als der korrekte erzeugte Code tatsächlich [document myComment] schlägt.

+0

Aber zur Laufzeit weiß es nicht den eigentlichen Typ des Dokuments, aber es ist immer noch erfolgreich mit Standard-Empfänger-Methode-Syntax. Dies ist eine dynamische Sprache. Natürlich werden die Eigenschaften von document.comment mit der von Ihnen bereitgestellten Property-Deklaration fehlschlagen, was durchaus sinnvoll ist.Der Compiler hat den gleichen Mangel an Informationen in der Empfänger-Methode Syntax Beispiel, aber der Compiler ließ es gehen. Sie können einen nicht existierenden Methodennamen verwenden und der Compiler wird ihn auch loslassen. – ctpenrose

+0

Die Kompilierung akzeptiert nur '[Dokumentenkommentar]' ohne Beschwerde, wenn sie weiß, dass irgendwo eine Methode namens -comment für ein Objekt existiert. Wenn Sie '[Dokument sdlkjf]' eingeben, erhalten Sie stattdessen eine Warnung. Aber Sie haben Recht, Methoden verwenden dynamische Dispatch und werden nur zur Laufzeit fehlschlagen, wenn das Objekt nicht tatsächlich diese Nachricht behandelt. Auf der anderen Seite sind Eigenschaften ein Kompilierzeitmerkmal und der Eigenschaftszugriff wird daher zur Kompilierzeit aufgelöst. –

+1

... und wenn es drei 'comment'-Methoden gibt, eine, die' NSString * 'zurückgibt, eine' char * '- und eine, die eine Struktur zurückgibt, ist die Dynamik sowieso aus dem Fenster. Die Realität ist, dass Objective-C sehr viel eine statisch typisierte Sprache ist, ohne dass diese statische Typisierung sowohl dem dynamischen Dispatch als auch dem Polymorphismus im Wege steht. – bbum

3

Kevin eines der Symptome genagelt.

Beim Entwerfen von Eigenschaften wurde die sehr spezifische Entscheidung nicht getroffen, um id als das Ziel der Punktsyntax zu unterstützen. Abgesehen von den Zweideutigkeiten, auf die Kevin hinweist, wurde der Wunsch, alle Mehrdeutigkeiten im Zusammenhang mit (ID) -Empfängern zu vermeiden, als wünschenswert erachtet.

Im Allgemeinen ist die Verwendung von vollständig unqualifizierten id sowohl unerwünscht als auch aktiv abgeraten. Bei der Erstellung neuer Features in der Sprache verhindert die Unterstützung von id die Verbreitung fragiler Codierungsmuster in den neuen Features nicht.

+0

Ich stimme nicht zu. Es fügt ein asymmetrisches statisches typisiertes Merkmal hinzu. Sie unterdrückt, zumindest syntaktisch, ein nützliches dynamisches Merkmal der Sprache, wenn sie Eigenschaften verwendet. Ich frage mich, was die ursprünglichen Stepstone-Architekten dazu sagen würden. Einige haben möglicherweise gegen Eigenschaften völlig gekämpft. Ich mag ihre Bequemlichkeit, aber die Asymmetrie ist in mehreren spezifischen Situationen frustrierend. Protokolle können verwendet werden, um die so genannten "fragilen Codierungsmuster" zu eliminieren, die Sie erwähnen. – ctpenrose

+0

Statisches Tippen ist keine schlechte Sache. Ich denke, dass Obj-C eine ziemlich gute Balance zwischen dynamischem Tippen und statischem Tippen findet, wobei einige Merkmale dynamischer sind als andere. Eigenschaften sind so ziemlich ein Kompilierzeit-Feature (der einzige Einfluss auf die Laufzeit, den ich mir vorstellen kann, ist, dass die Metadaten über Laufzeitmethoden verfügbar sind) und fallen somit in die Kategorie der statischen Typisierung. –

+0

Brad Cox mag die Richtung, die die Sprache genommen hat. Ich verstehe, wo Ihre Kritik liegt, aber ich sehe sie nicht als ausreichend anwendbar an, um die durch das dynamische Schreiben bedingte Fragilität in Kauf zu nehmen. Vor einiger Zeit - 1996ish, oder so IIRC - wurde die Entscheidung getroffen, so weit wie möglich von der generischen Typisierung abzuweichen. Beachten Sie, dass Sie bei bestimmten problematischen Mustern einen Fehler melden oder eine SO-Frage stellen müssen! – bbum

Verwandte Themen