Почему я не могу получить метод экземпляра моей категории даже после его вызова?

Я пытаюсь немного лучше понять среду выполнения Objective-C. Рассмотрим NSAttributedString.h с минимальным интерфейсом, за которым следует более обширная категория NSExtendedAttributedString.

Теперь рассмотрим следующий код:

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

Мы находим метод экземпляра, который является частью канонического интерфейса, но не тот, что в категории. Как это может происходить и при этом успешно вызываться? Есть ли способ самоанализа и поиска метода категорий?


person Ben Flynn    schedule 19.04.2013    source источник


Ответы (1)


Что происходит в этом случае, так это то, что вы предполагаете, что attributedString имеет тип NSAttributedString, что не так:

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

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

Если вы измените NSAttributedString.class в своем коде на [attributedString class], он будет работать как положено.

person proxi    schedule 19.04.2013
comment
Но initWithAttributedString определяется в категории NSAttributedString, а не в NSConcreteAttributedString. - person Martin R; 19.04.2013
comment
Хороший звонок и хорошее напоминание не ожидать, что только потому, что вы выделяете/инициализируете что-то, вы получите что-то из этого класса обратно. - person Ben Flynn; 19.04.2013
comment
Я знал, что initXXX может возвращать другой объект, но здесь [NSAttributedString alloc] уже возвращает экземпляр NSConcreteAttributedString. Раньше я не замечал такого поведения! - person Martin R; 19.04.2013