开发者

Does Objective-C have reflection?

开发者 https://www.devze.com 2023-04-08 04:13 出处:网络
I\'m doing research about Objective-C, and I\'d like to know if it has th开发者_如何学JAVAe concept of reflection. None of the documents I\'ve found so far describes reflection.There are runtime funct

I'm doing research about Objective-C, and I'd like to know if it has th开发者_如何学JAVAe concept of reflection. None of the documents I've found so far describes reflection.


There are runtime functions described in Runtime Reference which allows not only querying for features of a class or an instance, but also adding a method, or even creating a new class at runtime. I say this is a very dynamic kind of reflection, which was not usually available to C-based languages. Mike Ash's wrappers is an Objective-C wrapper around that. Again, it can even add methods! The base class of Cocoa, NSObject, also provide wrappers for many of the runtime functions, see NSObject protocol reference. For example

     [foo respondsToSelector:@selector(bar:)];

     if([foo isKindOfClass:[NSString class]]){ ... } 

does what the method names say. You can even add a method on the fly. For example,

   #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;
  }

This produces the output

  Hi! from aeiou
  Hi! from bark
  Hi! from mew

What it does is as follows:

  1. SEL is the variable which represents the sent message (or method call, in the other terminology.)
  2. Objective-C runtime calls resolveInstanceMethod: of a class if a message sent to an instance is not implemented in the class
  3. So, in this case, I just copy an implementation of a predefined method called sayHi to that method's implementation.
  4. From the method, you can use _cmd to see what was the selector used in calling the method. So, even from a single sayHi implementation, we can get different output.

Some of the standard Cocoa's implementation (Key-Value-Coding, Key-Value-Observing and Core Data in particular) uses the runtime to dynamically modify the class.


Yes, Objective-C has reflection (and abstract classes). Whether that reflection fits your needs or not is a different question.

Reflection in Objective-C is surprisingly flexible for a C derived language. You can ask a class what methods it implements or you can modify and/or add methods to existing classes. You can even create new classes on the fly or change the class of any instance at any time.

A typical Objective-C program does none of theses things (at least not directly) save for occasionally calling respondsToSelector: or conformsToProtocol:. While Objective-C is a fully dynamic, reflective, object oriented language, that doesn't mean that such patterns are encouraged or typically used.

You might find my answers to these questions interesting:

In Objective C, how to find out the return type of a method via reflection?

Does Objective-C have a Standard Library?

Smalltalk runtime features absent on Objective-C?

And, of course, the runtime is very well documented. As is the language. Or you could read the source.


I guess I don't know what aspect of reflection you're looking for. Are you looking for how to determine which class a given variable is? If so, check this out: Objective-C class -> string like: [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:)]

Are you looking for more than just this?


There are a flock of methods that can access various properties of a class and, presumably, "peek" and "poke" at some object internals. I've never played with them, and a little reading that I've done suggests that they're far from perfect, but they do appear to offer some ability for "reflection", similar to the Java concept.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号