Есть ли в Objective-C отражение? - PullRequest
       0

Есть ли в Objective-C отражение?

21 голосов
/ 26 сентября 2011

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

Ответы [ 4 ]

25 голосов
/ 26 сентября 2011

Существуют функции времени выполнения, описанные в Справочник времени выполнения , который позволяет не только запрашивать функции класса или экземпляра, но также добавлять метод или даже создавать новый класс во время выполнения.Я говорю, что это очень динамичный вид отражения, который обычно не был доступен для языков на Си. Обертки Майка Эша - это оболочка 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

. Это происходит следующим образом:

  1. SEL - это переменная, которая представляетотправленное сообщение (или вызов метода в другой терминологии.)
  2. вызовы времени выполнения Objective C resolveInstanceMethod: класса, если сообщение, отправленное экземпляру, не реализовано в классе
  3. Такв этом случае я просто копирую реализацию предопределенного метода с именем sayHi в реализацию этого метода.
  4. Из метода вы можете использовать _cmd, чтобы увидеть, какой селектор использовался при вызове метода,Таким образом, даже из одной sayHi реализации мы можем получить различный вывод.

Некоторые из стандартных реализаций Cocoa (в частности, Key-Value-Coding, Key-Value-Observing и Core Data)использует динамическую среду для динамического изменения класса.

13 голосов
/ 26 сентября 2011

Да, у Objective-C есть отражение (и абстрактные классы). Подходит ли это отражение вашим потребностям или нет - это другой вопрос.

Отражение в Objective-C на удивление гибко для языка, производного от C. Вы можете спросить класс, какие методы он реализует, или вы можете изменить и / или добавить методы к существующим классам. Вы даже можете создавать новые классы на лету или изменять класс любого экземпляра в любое время.

Типичная программа Objective-C не выполняет ничего из этих вещей (по крайней мере, не напрямую), за исключением случайного вызова respondsToSelector: или conformsToProtocol:. Хотя Objective-C является полностью динамическим, рефлексивным, объектно-ориентированным языком, это не означает, что такие шаблоны поощряются или обычно используются.

Вы можете найти мои ответы на эти вопросы интересными:

В Задаче C как узнать тип возвращаемого значения метода с помощью отражения?

Есть ли в Objective-C стандартная библиотека?

Функции выполнения Smalltalk отсутствуют в Objective-C?

И, конечно, время выполнения очень хорошо задокументировано . Как и язык . Или вы можете прочитать источник .

1 голос
/ 26 сентября 2011

Существует множество методов , которые могут обращаться к различным свойствам класса и, по-видимому, "peek" и "poke" в некоторых внутренних объектах объекта.Я никогда не играл с ними, и небольшое чтение, которое я сделал, показывает, что они далеки от совершенства, но, похоже, они предлагают некоторую способность к «размышлению», аналогичную концепции Java.

1 голос
/ 26 сентября 2011

Думаю, я не знаю, какой аспект отражения вы ищете.Вы ищете, как определить, к какому классу относится данная переменная?Если так, проверьте это: Класс Objective C -> строка как: [NSArray className] -> @ "NSArray"

// Get a object's class name
if ([NSStringFromClass([foo class]) compare:@"NSSomeObject"] == NSOrderedSame) {...}

// Does an object have a method
[foo respondsTo:@selector(method:)]

Вы ищете больше чем это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...