Ответ 1
Существуют функции выполнения, описанные в Runtime Reference, которая позволяет не только запрашивать функции класса или экземпляра, но также добавлять метод или даже создавать новую класса во время выполнения. Я говорю, что это очень динамичный вид рефлексии, который обычно не был доступен для языков на основе C. Обертки Mike Ash - это обертка Objective-C. Опять же, он может даже добавлять методы! Базовый класс Cocoa, NSObject
также предоставляет оболочку для многих функций времени исполнения, см. NSObject
ссылку на протокол. Например
[foo respondsToSelector:@selector(bar:)];
if([foo isKindOfClass:[NSString class]]){ ... }
делает то, что говорят имена методов. Вы даже можете добавить метод "на лету". Например,
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Foo:NSObject
{
}
@end
@implementation Foo
-(void)sayHi
{
NSLog(@"Hi! from %@",NSStringFromSelector(_cmd));
}
+(BOOL)resolveInstanceMethod:(SEL)sel
{
Method method=class_getInstanceMethod(self,@selector(sayHi));
class_addMethod(self,sel,method_getImplementation(method),method_getTypeEncoding(method));
return YES;
}
@end
int main(){
NSAutoreleasePool*pool=[[NSAutoreleasePool alloc] init];
Foo* foo=[[Foo alloc] init];
[foo aeiou];
[foo bark];
[foo mew];
[pool drain];
return 0;
}
Это приводит к выходу
Hi! from aeiou
Hi! from bark
Hi! from mew
Что он делает, так выглядит:
-
SEL
- это переменная, представляющая отправленное сообщение (или вызов метода в другой терминологии). - Objective-C runtime вызывает
resolveInstanceMethod:
класса, если сообщение, отправленное экземпляру, не реализовано в классе - Итак, в этом случае я просто копирую реализацию предопределенного метода с именем
sayHi
в реализацию этого метода. - Из метода вы можете использовать
_cmd
, чтобы узнать, какой был селектор, используемый при вызове метода. Таким образом, даже из одной реализацииsayHi
мы можем получить другой результат.
Некоторые из стандартных реализаций Cocoa (Key-Value-Coding, Key-Value-Observing и Core Data в частности) используют среду выполнения для динамического изменения класса.