son*_*.vu 21 reflection objective-c
我正在研究Objective-C,我想知道它是否具有反射的概念.到目前为止,我发现的文件都没有描述反思.
Yuj*_*uji 26
Runtime Reference中描述了运行时函数,它不仅允许查询类或实例的功能,还允许添加方法,甚至在运行时创建新类.我说这是一种非常动态的反射,通常不适用于基于C语言.Mike Ash的包装器是一个Objective-C包装器.再次,它甚至可以添加方法!Cocoa的基类NSObject也提供了许多运行时函数的包装器,请参阅NSObject协议引用.例如
[foo respondsToSelector:@selector(bar:)];
if([foo isKindOfClass:[NSString class]]){ ... }
Run Code Online (Sandbox Code Playgroud)
做方法名称所说的.您甚至可以动态添加方法.例如,
#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;
}
Run Code Online (Sandbox Code Playgroud)
这会产生输出
Hi! from aeiou
Hi! from bark
Hi! from mew
Run Code Online (Sandbox Code Playgroud)
它的作用如下:
SEL 是表示已发送消息(或方法调用,在其他术语中)的变量.resolveInstanceMethod:如果在类中未实现发送到实例的消息,则为Objective-C运行时调用类sayHi该方法实现的预定义方法的实现._cmd查看调用该方法时使用的选择器.因此,即使从单个sayHi实现,我们也可以获得不同的输出.一些标准的Cocoa实现(特别是Key-Value-Coding,Key-Value-Observing和Core Data)使用运行时动态修改类.
bbu*_*bum 14
是的,Objective-C有反射(和抽象类).这种反思是否符合您的需求是一个不同的问题.
Objective-C中的反射对于C派生语言来说非常灵活.您可以向类询问它实现的方法,或者可以修改和/或向现有类添加方法.您甚至可以动态创建新类或随时更改任何实例的类.
一个典型的Objective-C程序没有做任何事情(至少不是直接的)除了偶尔调用respondsToSelector:或conformsToProtocol:.虽然Objective-C是一种完全动态的,反射的,面向对象的语言,但这并不意味着鼓励或通常使用这种模式.
您可能会发现我对这些问题的答案很有趣:
在Objective C中,如何通过反射找出方法的返回类型?
当然,运行时也有很好的记录.就像语言一样.或者你可以阅读来源.
| 归档时间: |
|
| 查看次数: |
16658 次 |
| 最近记录: |