7
votes

Comment obtenir des métadonnées de type bloc d'exécution dans l'objectif-C?

J'écris une classe où vous enregistrez un objet et une propriété à observer. Lorsque la propriété est définie sur quelque chose de non- nil code>, un sélecteur de rappel enregistré est appelé (comme cible-action). Le sélecteur peut avoir trois signatures différentes et la bonne est appelée en fonction du type enregistré.

Cela fonctionne bien, mais maintenant, je souhaite ajouter la possibilité d'enregistrer un bloc à la place d'un sélecteur comme "Fonction de rappel". Est-il possible de trouver la signature de fonction du bloc fourni et de gérer le rappel différemment en fonction du type de bloc fourni? P>

Par exemple: P>

- (void)registerCallbackBlock:(id)block
{
    if ([self isBlock:block] {
        if ([self isMethodSignatureOne:block]) { /* */ }
        else if ([self isMethodSignatureTwo:block]) { /* */ }
        else { assert(false); }  // bad Block signature

        block_ = block;  // assuming ARC code
    }
    else { assert(false); } // not a block
} 

- (void)callBlock 
{
    if ([self isMethodSignatureOne:block_] {
        block_(arg1_, arg2_);         // needs casting?
    }
    else if ([self isMethodSignatureTwo:block_) {
        block_(arg1_, arg2_, arg3_);  // needs casting?
    }
}


1 commentaires

Vous pourrez peut-être simplement prétendre que cela avait 3 arguments, même si cela prend vraiment 1 ou 2, car des arguments supplémentaires seront juste ignorés


3 Réponses :


3
votes

Je ne crois pas que cela soit réellement possible avec l'ABI actuel. Cependant, vous pouvez faire quelque chose comme ceci: xxx


1 commentaires

Merci pour la bonne idée d'utiliser un bloc d'enveloppe pour gérer des arguments facultatifs. Dans mon cas, les augmentations sont assez différentes pour les deux méthodes de rappel enregistrées et il ne serait pas possible d'utiliser cette méthode. Et je suis désolé d'avoir donné la réponse acceptée à Chris Devereux - vous êtes juste aussi juste que lui, mais j'ai été charmé par ses informations détaillées sur Clang.



5
votes

Si vous compilez avec Clang, vous pouvez obtenir ces informations.

à partir du CLANG Block ABI SPEC :

L'ABI des blocs consiste en leur présentation et les fonctions d'exécution requises par le compilateur. Un bloc consiste en une structure de la forme suivante: xxx

Les bits de drapeaux suivants sont utilisés donc pour un possible ABI.2010.3.16: xxx

dans la pratique, la version actuelle de Clang code des informations de signature. Selon un commentaire ici , le format est juste une chaîne de codage de méthode Objective-C standard. Cela dit, le format de signature n'est pas documenté (comme le SAF que possible de le dire), donc je ne sais pas combien vous pouvez supposer que cela ne cassera pas avec les mises à jour du compilateur.


1 commentaires

Merci beaucoup pour les informations détaillées! Ainsi, les informations sont là mais ne sont pas officiellement sanctionnées à utiliser. En pratique, cela signifie que je devrai vous tenir à une API plus brut avec plusieurs méthodes d'enregistrement. Cela fonctionne toujours, mais j'espère qu'Apple documentera ces informations à l'avenir et / ou publiera une nouvelle API pour obtenir les informations de signature de bloc de la «voie officielle».



1
votes

Oui, nous pouvons, car je répondit dans un autre question .

La structure de bloc est une norme de clang publiée et Afaik, peut être utilisée tout ce que vous voulez.


0 commentaires