Я занимаюсь исследованием Objective-C, и я хотел бы знать, имеет ли он концепцию отражения. Ни один из документов, которые я нашел до сих пор, не описывает отражение.
Отражает ли Objective-C отражение?
Ответ 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 в частности) используют среду выполнения для динамического изменения класса.
Ответ 2
Да, Objective-C имеет отражение (и абстрактные классы). Независимо от того, соответствует ли это отражение вашим потребностям или нет, это другой вопрос.
Отражение в Objective-C удивительно гибко для языка C. Вы можете спросить класс, какие методы он реализует, или вы можете модифицировать и/или добавлять методы к существующим классам. Вы даже можете создавать новые классы "на лету" или изменять класс любого экземпляра в любое время.
Типичная Objective-C программа не выполняет ни одной из тезисов (по крайней мере, не напрямую), за исключением случаев, когда вы вызываете respondsToSelector:
или conformsToProtocol:
. Хотя Objective-C является полностью динамическим, отражающим, объектно-ориентированным языком, это не означает, что такие шаблоны поощряются или обычно используются.
Вы можете найти мои ответы на эти вопросы:
В Objective C, как узнать тип возвращаемого метода путем отражения?
Имеет ли Objective-C стандартную библиотеку?
Функции времени выполнения Smalltalk отсутствуют на Objective-C?
И, конечно же, время выполнения очень хорошо документировано. Как язык. Или вы можете прочитать источник.
Ответ 3
Я думаю, я не знаю, какой аспект рефлексии вы ищете. Вы ищете, как определить, какой класс является данной переменной? Если это так, проверьте это: Objective-C class → string like: [NSArray className] → @ "NSArray"
// Get a object class name
if ([NSStringFromClass([foo class]) compare:@"NSSomeObject"] == NSOrderedSame) {...}
// Does an object have a method
[foo respondsTo:@selector(method:)]
Вы ищете больше, чем просто это?
Ответ 4
Существует стая методов, которая может обращаться к различным свойствам класса и, предположительно, "заглядывать" и "выталкивать" на какой-либо объект внутренности. Я никогда не играл с ними, и небольшое чтение, которое я сделал, говорит о том, что они далеки от совершенства, но они, похоже, предлагают некоторые возможности для "отражения", похожие на концепцию Java.