Подтвердить что ты не робот

Отражает ли Objective-C отражение?

Я занимаюсь исследованием Objective-C, и я хотел бы знать, имеет ли он концепцию отражения. Ни один из документов, которые я нашел до сих пор, не описывает отражение.

4b9b3361

Ответ 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.