web-dev-qa-db-fra.com

Cas d'utilisation de «oneway void» dans Objective-C?

J'ai trouvé un mot-clé étrange dans NSObject.h

- (oneway void)release;

J'ai cherché sur le Web et j'ai appris que cela se rapportait à la transmission de messages asynchrone, qui ressemble à la transmission de messages d'Erlang.

Il semble que cela puisse faire beaucoup de choses intéressantes. Quels sont les bons cas d'utilisation de ce mot clé?

105
Eonil

oneway est utilisé avec l'API des objets distribués, qui permet d'utiliser des objets objective-c entre différents threads ou applications. Il indique au système qu'il ne doit pas bloquer le thread appelant jusqu'à ce que la méthode revienne. Sans cela, l'appelant se bloquera, même si le type de retour de la méthode est nul. De toute évidence, il n'est jamais utilisé avec autre chose que void, car cela signifierait que la méthode renvoie quelque chose, mais l'appelant ne l'obtient pas.

Pour plus d'informations sur les objets distribués, voir Cocoa Conceptual DistrObjects .

108
ughoavgfhw

Il semble également nécessaire d'éliminer un avertissement avec XCode 4.2 (LLVM). Plus précisément:

-(void) release { }

donne l'avertissement suivant dans XCode 4.2 (avec LLVM):

avertissement: problème sémantique: conflits de modificateurs d'objets distribués sur le type de retour dans l'implémentation de 'release'

L'avertissement peut être éliminé en ajoutant le modificateur unidirectionnel:

-(oneway void) release { }

C'est dans l'implémentation d'un singleton, donc la version ne fait vraiment rien.

Cela est nécessaire (au moins pour éliminer l'avertissement) sur iOS ainsi que sur OS X. Le protocole NSObject dans les documents iOS définit la version comme (à sens unique nul) même s'il n'y a pas d'objets distribués dans iOS. Il semble que LLVM le ramasse alors que GCC ne le fait pas.

38
jeffc666

Selon la documentation d'Apple, oneway n'est utilisé que pour les objets distribués (et non pour le multithreading).

Le modificateur unidirectionnel n'est utilisé que si l'objet est distant. Dans ce cas, l'appel de libération peut retourner de manière asynchrone (avant la fin de la méthode). Dans un réseau, cela a du sens car l'attente d'un message de retour peut prendre un certain temps.

La méthode de libération n'a pas de valeur de retour et l'appel peut donc être exécuté de manière asynchrone. En revanche, conserver et libérer automatiquement renvoyer un identifiant et nous devons donc attendre que le message de retour soit transféré à travers le réseau.

18
Freeman