Ho definito il mio protocollo. Ho menzionato due dei miei metodi di protocollo come facoltativi. Durante l'esecuzione, come posso sapere se il particolare metodo è opzionale o no? C'è un modo per scoprirlo?Come identificare un metodo di protocollo è opzionale durante il runtime?
risposta
Questo dovrebbe fare quello che vuoi:
BOOL MethodInProtocolIsRequired(Protocol *protocol, SEL methodSelector)
{
struct objc_method_description methodDesc = protocol_getMethodDescription(protocol, methodSelector, YES, YES);
return methodDesc.name != NULL;
}
Si noti che non sto commentando l'opportunità di utilizzare questo nel codice di spedizione, soprattutto perché non hai spiegato il motivo per cui vuoi farlo. Si noti inoltre che questa funzione restituirà NO quando viene fornito un selettore per un metodo che il protocollo non contiene. Questo è fondamentalmente ragionevole (dopotutto, se un protocollo non contiene un metodo, non è necessario!), Ma è possibile aggiungere sofisticazione alla funzione controllando se il protocollo contiene il metodo come metodo opzionale e restituisce qualcosa di diverso per tutti e tre gli scenari (richiesto, facoltativo, non-in-protocollo).
EDIT: programma di test semplice qui: https://gist.github.com/4381753
Dovrei fare davvero questo invece del mio approccio complicato. +1. (Posso incorporare questo nella mia risposta?) –
Ovviamente, e vedo che l'hai già fatto :). –
sì, e ho fatto in modo di aggiungere l'attribuzione :) Questa volta sono io che dovrei avere RTFM ... -.- –
(non so la risposta al largo della parte superiore della mia testa. 1 minuto di googling mi ha aiutato.)
Si può fare questo usando la funzione protocol_copyMethodDescriptionList()
che fa parte del runtime Objective-C libreria (libobjc). Il secondo argomento di questa funzione è un flag booleano che indica se sono richiesti i metodi da copiare nel protocollo. Quindi, se un metodo è nella lista restituita da questa funzione (chiamata usando gli argomenti appropriati), allora è un metodo obbligatorio.
SEL sctr = @selector(isThisMethod:requiredIn:theProtocol:);
struct objc_method_description *methods;
unsigned int nMethods;
methods = protocol_copyMethodDescriptionList(
objc_getProtocol("MyProtocolName"), // or @protocol(MyProtocolName) if you don't need this kind of dynamism
YES, // required?
YES, // instance method? (in general, protocols declare instance methods)
&nMethods
);
BOOL isRequired = NO;
int i;
SEL s;
const char *sctrStr = sel_getName(sctr);
for (i = 0; i < nMethods; i++) {
s = methods[i].name;
const char *sStr = sel_getName(s);
if (strcmp(sctrScr, sStr) == 0) {
isRequired = YES;
break;
}
}
free(methods);
if (isRequired) {
// required
} else {
// optional
}
Quindi, questo è possibile, ma è un po 'di un eccessivo, e come ho già detto nel mio commento alla tua domanda, non si dovrebbe verificare un metodo di essere opzionale o necessario, si dovrebbe verificare un istanza che risponde a un particolare selettore.
Modifica: sì, invece di copiare l'intero universo, avrei dovuto leggere più avanti nella documentazione. Come Andrew Madsen ha sottolineato, questo può essere ridotto a poche righe:
struct objc_method_description method;
method = protocol_getMethodDescription(
objc_getProtocol("MyProtocolName"), // or @protocol(MyProtocolName)
@selector(isThisSelector:required:)
YES, // required?
YES // instance method?
);
if (method.name != NULL) {
// required
} else {
// optional
}
Perché mai sulla Terra sarebbe cambiato il suo upvote a un downvote? –
Se solo tu stavi usando GNU c booleans, puoi finalmente dire che hai risposto a una domanda-obiettivo senza alcun ObjC! (Estremamente tecnicamente però). – CodaFi
@CodaFi: O C99 'bool' /' _Bool'. –
- 1. Verificare se il metodo di protocollo opzionale è implementato in Swift?
- 2. imagePickerController: didFinishPickingMediaWithInfo conflitti con metodo requisito opzionale in protocollo 'UIImagePickerControllerDelegate'
- 3. Swift: impostazione di una proprietà opzionale di un protocollo
- 4. perché un [n] è accettato in c durante il runtime?
- 5. Un metodo con un parametro opzionale
- 6. Tipo di modello durante il runtime
- 7. Il socket non è in grado di identificare il protocollo (perdita socket)
- 8. Come arrivare Hibernate dialetto durante il runtime
- 9. protocollo per il metodo di classe
- 10. Codice iOS per identificare il supporto del metallo in runtime?
- 11. Come identificare il metodo di override nel codice byte Java?
- 12. Compilazione di String come codice durante il runtime su Android
- 13. Creazione di una classe durante il runtime
- 14. Come identificare ciascun tipo di parametro in un metodo C#?
- 15. Java Opzionale perché non un metodo ifNotPresent?
- 16. è possibile sovrascrivere un metodo in fase di runtime?
- 17. Come identificare se il token OAuth è scaduto?
- 18. Come identificare il numero di porta DB2
- 19. Modifica delle impostazioni dell'app durante il runtime
- 20. 'Self' è disponibile solo in un protocollo o come risultato di un metodo di classe
- 21. Reload classi durante il runtime JVM
- 22. Visualizzazioni duplicate su Android durante il runtime
- 23. Aggiungi flag durante il runtime (Xcode Instruments)
- 24. Runtime Objective-C: il modo migliore per verificare se la classe è conforme al protocollo?
- 25. Come posso verificare qual è il valore predefinito per parametro opzionale nel metodo di ruby?
- 26. Come decidere se un argomento opzionale è stato dato o meno in un metodo ruby
- 27. Evidenzia elementi in WebDriver durante il runtime
- 28. Come eseguire il cast su un oggetto per un tipo quando il tipo è noto durante il runtime?
- 29. Come identificare se il riferimento di classe è un'interfaccia?
- 30. Come identificare il contenuto di un byte [] è un file jpeg?
Perché questa informazione è necessaria in fase di esecuzione? (Solo curioso.) –
@NikolaiRuhe Sì, +1 per quel commento. In generale, non dovremmo fare supposizioni ma testare le caratteristiche. I. e., Si dovrebbe testare per 'respondsToSelector:' invece di assumere che sia implementato un metodo obbligatorio. –
Oppure puoi creare tu stesso un dizionario con tutti i nomi dei metodi come chiave e il suo valore come SÌ/NO per verificare se è richiesto o meno. –