2013-04-19 8 views
5

Ich versuche, die Objective-C-Laufzeit ein wenig besser zu verstehen. Betrachten Sie NSAttributedString.h, die eine minimale Schnittstelle gefolgt von einer umfangreicheren Kategorie NSExtendedAttributedString hat.Warum kann ich meine Kategorieinstanzmethode nicht erhalten, nachdem ich sie aufgerufen habe?

Betrachten wir nun den folgenden Code:

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 

Wir finden die Instanzmethode, die Teil der kanonischen Schnittstelle ist, aber nicht die, die in der Kategorie. Wie kann das passieren und dennoch kann es erfolgreich aufgerufen werden? Gibt es eine Möglichkeit, die Kategoriemethode zu betrachten und zu finden?

Antwort

3

Was passiert in diesem Fall ist, dass Sie attributedString nehmen NSAttributedString als Typ, was nicht der Fall ist:

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

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

Wenn Sie NSAttributedString.class in Ihrem Code [attributedString class] ändern wird es wie erwartet funktionieren.

+0

InitWithAttributedString ist jedoch in einer Kategorie von NSAtributedString definiert, nicht von NSConcreteAttributedString. –

+0

Guter Anruf und eine gute Erinnerung, um nicht zu erwarten, dass Sie etwas von dieser Klasse zurückbekommen, nur weil Sie etwas zuweisen. –

+1

Mir war klar, dass 'initXXX' ein anderes Objekt zurückgeben kann, aber hier gibt '[NSAttributedString alloc]' 'bereits eine Instanz von' NSConcreteAttributedString' zurück. Ich hatte dieses Verhalten vorher nicht bemerkt! –