Domanda

Objective-C utilizza binding dinamico:. Cioè chiamate di metodo vengono risolte in fase di esecuzione

Bene.

E di notazione punto davvero si riduce a una chiamata di metodo

Ma perché allora, non posso fare qualcosa di simile:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];


  // Intercept the exception
  @try
  {
    @throw [ NSException 
            exceptionWithName:@"Exception named ME!" 
            reason:@"Because i wanted to" 
            userInfo:nil ] ;
  }
  @catch( id exc ) // pointer to an exception object?
  {



    //NSLog( @"%@ : %@\n", exc.name, exc.reason ) ; // ILLEGAL:  Request for member 
    // 'name' in something not a structure or union..
    // If objective-c uses dynamic binding, and dot notation
    // boils down to calling the getter, then
    // WHY do I have to cast to the concrete type here?

    // Only works if I cast to the concrete type NSException*
    NSException* nexc = (NSException*)exc ;
    NSLog( @"%@ : %@\n", nexc.name, nexc.reason ) ;



  }



  [pool drain];
    return 0;
}

Quando sento "binding dinamico" Sto pensando "e quindi dovrebbe comportarsi come un linguaggio di scripting", e sono sorpreso di come inflessibile Objective-C sembra paragonato a un linguaggio di scripting come JavaScript .

È stato utile?

Soluzione

Stai confondendo il runtime e il compilatore. Il runtime non ha alcun problema far fronte a questo. Il problema è che la notazione punto (che è zucchero sintattico) richiede digitare le informazioni per il compilatore di disambiguare tra oggetti Objective-C e le strutture C.

Se non si utilizza notazione del punto funziona:

NSLog( @"%@ : %@\n", [exc name], [exc reason]) ;

È possibile che questo genererà un avviso se il tipo non è id poiché il compilatore sa che conosce il tipo e non può garantire l'invio funzionerà, ma sarà compilato ed eseguito.

Fondamentalmente la questione a portata di mano è il compilatore ha bisogno di sapere se generare un carico struttura, o un C dispaccio obiettivo, in altre parole, con la notazione del punto ha bisogno di avere informazioni sufficienti per determinare la differenza tra un oggetto e uno scalare tipo.

Altri suggerimenti

binding dinamico non è sinonimo di tipizzazione dinamica . C è un linguaggio fortemente tipizzato e, in particolare, il tipo di un valore di argomento o di ritorno è critica e può avere un impatto significativo generazione del codice.

Le proprietà sono specificamente progettati per eliminare l'ambiguità. Come parte di questo, è stata presa la decisione di non permettono la sintassi del punto per essere usato contro id.

In particolare, affronta questa situazione:

@interface Foo
- (short) length;
@end

@interface Bar
- (unsigned long long) length;
@end

Dato quanto sopra in due file di intestazione separati, compilazione di [anObject length] darà un avvertimento solo di entrambi i file di intestazione sono stati importati . Se solo un file di intestazione è stato importato, allora il sito chiamata verrà compilato il ritorno del tipo visto nell'intestazione. Se il sito chiamata fosse per il altro metodo, un risultato molto inaspettato sarebbe ritornato.

La limitazione della sintassi punto elimina questo potenziale ambiguità. Questo è anche il motivo per cui si non in generale vedi le dichiarazioni di co-variante di metodi. Il C ABI semplicemente non supporta in modo pulito (con quello detto, Objective-C fa un pessimo lavoro di sostegno tipo di oggetto co-varianza).

In realtà, gli sviluppatori di Objective-C raramente usano il tipo id. dichiarazioni di tipo specifiche permettono al compilatore di migliorare in modo significativo la sua validazione del codice.

Objective-C supporta binding dinamico. Tuttavia, non è possibile utilizzare le proprietà sugli oggetti di tipo 'id' - ma è possibile inviare eventuali messaggi che si desidera. (Questo è probabilmente un errore nella attuale definizione / implementazione ... Ma lasciamo che parte per ora.)

Se avete fatto

NSLog(@"%@ : %@", [exc name], [exc reason] ); 

allora che avrebbe funzionato. Si noti che non è necessario mettere un ritorno a capo in una dichiarazione NSLog, come sono tutti su righe separate in ogni caso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top