Question

Objective-C utilise la liaison dynamique:. Soit les appels de méthodes sont réglées lors de l'exécution

Fin

.

de notation dot se résume à un appel de méthode

Mais, pourquoi, je ne peux pas faire quelque chose comme ceci:

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

Quand j'entends « liaison dynamique » je pense « il devrait donc se comporter comme un langage de script », et je suis surpris de voir comment inflexible Objective-C semble par rapport à un langage de script comme JavaScript .

Était-ce utile?

La solution

Vous confondez l'exécution et le compilateur. Le temps d'exécution n'a pas de problème face à cela. Le problème est que la notation par points (ce qui est du sucre syntaxique) nécessite des informations de type pour le compilateur pour lever l'ambiguïté entre les objets Objective-C et C structs.

Si vous n'utilisez pas la notation de points cela fonctionne:

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

Ce qui précède va générer un avertissement si le type n'est pas id car le compilateur sait qu'il ne connaît le type et ne peut pas garantir l'envoi fonctionnera, mais il compiler et exécuter.

Au fond la question à l'est le compilateur a besoin de savoir si vous souhaitez générer une charge de la structure, ou une expédition Objective C, autrement dit, avec la notation des points, il doit avoir suffisamment d'informations pour déterminer la différence entre un objet et un scalaire le type.

Autres conseils

Liaison dynamique est pas synonyme de typage dynamique . C est un langage fortement typé et, en particulier, le type d'une valeur d'argument ou de retour est critique et peut avoir un impact significatif génération de code.

sont spécialement conçues pour éliminer toute ambiguïté. Comme une partie de cela, la décision a été prise à pas permettent la syntaxe de points à utiliser contre id.

Plus précisément, il aborde cette situation:

@interface Foo
- (short) length;
@end

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

Compte tenu de ce qui précède dans deux fichiers d'en-tête séparés, la compilation de [anObject length] donnera un avertissement uniquement des deux fichiers d'en-tête ont été importés . Si un seul fichier d'en-tête a été importé, le site d'appel sera compilé renvoyant le type vu dans l'en-tête. Si le site d'appel étaient pour autre méthode, un résultat très inattendu serait renvoyé.

La limitation de la syntaxe des points élimine cette ambiguïté potentielle. C'est aussi la raison pour laquelle vous ne pas voir généralement des déclarations de co-variantes de méthodes. L'ABI C juste ne supporte pas proprement (cela dit, Objective-C fait un mauvais travail de support de co-variance de type d'objet).

En réalité, les développeurs Objective-C utilisent rarement le type de id. Les déclarations de type spécifiques permettent au compilateur d'améliorer de manière significative sa validation de code.

Objective-C prend en charge la liaison dynamique. Cependant, vous ne pouvez pas utiliser des propriétés des objets de type « id » - mais vous pouvez l'envoyer tous les messages que vous souhaitez. (Ceci est probablement une erreur dans la définition actuelle / mise en œuvre ... mais laissons cela de côté pour l'instant.)

Si vous avez

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

il serait alors travailler. Notez que vous n'avez pas besoin de mettre une nouvelle ligne sur une déclaration NSLog, car ils sont tous sur des lignes séparées de toute façon.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top