2013-04-19 16 views
5

Sto cercando di capire un po 'meglio il runtime Objective-C. Si consideri NSAttributedString.h che ha un'interfaccia minima seguita da una più ampia categoria NSExtendedAttributedString.Perché non riesco a ottenere il metodo di istanza di categoria anche dopo averlo chiamato?

Consideriamo ora il seguente codice:

NSAttributedString *attributedString = [[NSAttributedString alloc] initWithAttributedString:[[NSAttributedString alloc] initWithString:@"ABC"]]; 
NSLog(@"Result: %@", attributedString); 
NSLog(@"Exists? %@", [NSString stringWithUTF8String:sel_getName(method_getName(class_getInstanceMethod(NSAttributedString.class, @selector(initWithAttributedString:))))]);  
NSLog(@"Exists? %@", [NSString stringWithUTF8String:sel_getName(method_getName(class_getInstanceMethod(NSAttributedString.class, @selector(string))))]); 

// Produces this output 
2013-04-19 10:17:35.364 TestApp[53300:c07] Result: ABC{ 
} 
2013-04-19 10:17:35.364 TestApp[53300:c07] Exists? <null selector> 
2013-04-19 10:17:35.365 TestApp[53300:c07] Exists? string 

troviamo il metodo di istanza che fa parte dell'interfaccia canonica, ma non quello della categoria. Come può accadere eppure può essere chiamato con successo? C'è un modo per introspettarsi e trovare il metodo di categoria?

risposta

3

Cosa succede in questo caso è che si assume attributedString essere di tipo NSAttributedString, che non è il caso:

NSLog(@"Class: %@", [attributedString class]); 

// Produces this output 
2013-04-19 19:50:21.955 TestApp[1611:303] Class: NSConcreteAttributedString 

Se si cambia NSAttributedString.class nel codice per [attributedString class] che funzionerà come previsto.

+0

Ma initWithAttributedString è definito in una categoria di NSAttributedString, non di NSConcreteAttributedString. –

+0

Una buona chiamata e un buon promemoria per non aspettarsi che solo perché assegnate/init qualcosa otterrete qualcosa di quel codice. –

+1

Ero consapevole del fatto che 'initXXX' può restituire un oggetto diverso, ma qui' [NSAttributedString alloc] 'restituisce già un'istanza di' NSConcreteAttributedString'. Non avevo notato questo comportamento prima! –