我正在研究Objective-C,我想知道它是否具有反射的概念。到目前为止,我发现的所有文件都没有描述反思。
答案 0 :(得分:25)
Runtime Reference中描述了运行时函数,它不仅允许查询类或实例的功能,还允许添加方法,甚至在运行时创建新类。我说这是一种非常动态的反射,通常不适用于基于C语言。 Mike Ash's wrappers是一个Objective-C包装器。再次,它甚至可以添加方法! Cocoa的基类NSObject
也为许多运行时函数提供了包装器,请参阅NSObject
protocol reference。例如
[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
是表示已发送消息的变量(或方法调用,在其他术语中。)resolveInstanceMethod:
sayHi
的预定义方法的实现复制到该方法的实现中。_cmd
查看调用该方法时使用的选择器。因此,即使从单个sayHi
实现,我们也可以获得不同的输出。一些标准的Cocoa实现(特别是Key-Value-Coding,Key-Value-Observing和Core Data)使用运行时来动态修改类。
答案 1 :(得分:13)
是的,Objective-C有反射(和抽象类)。这种反思是否符合您的需求是一个不同的问题。
Objective-C中的反射对于C派生语言来说非常灵活。您可以向类询问它实现的方法,或者可以修改和/或向现有类添加方法。您甚至可以随时创建新类或随时更改任何实例的类。
一个典型的Objective-C程序不会做任何事情(至少不会直接)保存,偶尔会调用respondsToSelector:
或conformsToProtocol:
。虽然Objective-C是一种完全动态的,反射的,面向对象的语言,但这并不意味着鼓励或通常使用这些模式。
您可能会发现我对这些问题的答案很有趣:
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?
当然,运行时为very well documented。和the language一样。或者你可以read the source。
答案 2 :(得分:1)
我想我不知道你在寻找什么方面的反思。您在寻找如何确定给定变量的类吗?如果是,请查看: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:)]
你还在寻找更多吗?
答案 3 :(得分:1)
有一群methods可以访问一个类的各种属性,并且可能是在一些对象内部“偷看”和“戳”。我从来没有和他们一起玩过,我所做的一点阅读表明他们远非完美,但他们似乎提供了一些“反思”的能力,类似于Java概念。