Così, sono stato nei guai con l'objc-runtime di nuovo (sorpresa sorpresa), e ho trovato un blocco di codice interessante here:Perché non possiamo usare le stringhe C come SEL?
const char *sel_getName(SEL sel) {
#if SUPPORT_IGNORED_SELECTOR_CONSTANT
if ((uintptr_t)sel == kIgnore) return "<ignored selector>";
#endif
return sel ? (const char *)sel : "<null selector>";
}
Allora, che cosa questo mi dice è che un SEL
è equivalente a una corda a C, in ogni manierismo. Facendo un esadecimale dei primi 16 byte di SEL che contiene @selector(addObject:)
dà la seguente:
61 64 64 4F 62 6A 65 63 74 3A 00 00 00 00 00 00
che è uguale a la stringa C addObject:
.
Detto questo, perché questo codice si arresta in modo anomalo quando utilizzo la stringa C come selettore?
SEL normalSEL = @selector(addObject:);
SEL cStringSEL = (SEL) "addObject:";
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"1", @"2", nil];
[arr performSelector:normalSEL withObject:@"3"];
[arr performSelector:cStringSEL withObject:@"4"];
NSLog(@"%@", arr);
Per quanto posso dire, il contenuto dei selettori sono gli stessi, quindi perché l'incidente sul secondo con il seguente messaggio di errore?
***
terminazione app a causa di eccezione non identificata 'NSInvalidArgumentException', motivo: '- [__ NSArrayM addObject:]: selettore non riconosciuto inviato ad esempio 0x101918720'***
Si noti che è possibile utilizzare 'sel_registerName()' per trasformare una stringa C in una SEL benedetta (in pratica, unifica la stringa dietro le quinte per conservare l'identità del puntatore successiva). Nota anche che non dovresti mai fare affidamento direttamente su un SEL come un 'char *'. Probabilmente lo sarà sempre, ma ciò non rende corretta l'ipotesi. – bbum