object c++如何实现反射机制
2012-11-15 09:23
627 查看
开发语言的反射机制为我们提供了发挥想象力的基础,通过反射可以设计出各种5花8门的架构来。
参考网上各种资料,Object c++的反射主要依靠下面的2个函数。
NSClassFromString
NSSelectorFromString
下面直接摆上例子,一目了然。
(一)通过一个字符串来创建对象并调用对象中的方法。
文件:Member.h
Cpp代码
// Member.h
#import <Foundation/Foundation.h>
@interface Member : NSObject {
NSString *name;
int age;
}
@property (nonatomic,copy) NSString *name;
@property int age;
@end
文件Member.m
Cpp代码
// Member.m #import "Member.h" @implementation Member @synthesize name,age; @end
测试代码文件Sample01.m:
Cpp代码
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//定义类名
NSString *className=@"Member";
//定义方法名
//注意:方法名后面要根据参数来设置,这里的setName:,表示setName
// 方法后面有1个参数
NSString *methodName=@"setName:";
//取得类并分配内存和初始化
id obj=[[NSClassFromString(className) alloc] init];
//调用类方法
[obj performSelector: NSSelectorFromString(methodName) withObject:@"Tom and Jerry."];
//显示
NSLog(@"%@",[obj name]);
[pool drain];
return 0;
}
代码执行后,显示如下:
2012-03-16 17:41:31.962 Sample01[39762:1307] Tom and Jerry.
由上面例子发现:
(1)在反射时,不需要使用import引入要反射的类;
(2)在定义反射类方法名时要注意后面的冒号,必须根据参数数量和原类方法名设置。
(二)通过字符串获取类的全部属性。
对上面的例子进行调整,如下面代码:(注意:在头部要引入头文件 objc/runtime.h)
Cpp代码
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//定义类名
NSString *className=@"Member";
//定义方法名
//注意:方法名后面要根据参数来设置,这里的setName:,表示setName
// 方法后面有1个参数
NSString *methodName=@"setName:";
//取得类并分配内存和初始化
id obj=[[NSClassFromString(className) alloc] init];
//调用类方法
[obj performSelector: NSSelectorFromString(methodName) withObject:@"Tom and Jerry."];
//显示
NSLog(@"%@",[obj name]);
//定义类属性的数量
unsigned propertyCount;
//获取对象的全部属性并循环显示属性名称和属性特性参数
objc_property_t *properties = class_copyPropertyList([obj class],&propertyCount);
for(int i=0;i<propertyCount;i++){
objc_property_t prop=properties[i];
NSLog(@"property:%s",property_getName(prop));
NSLog(@"property_getAttributes:%s",property_getAttributes(prop));
}
[pool drain];
return 0;
}
代码执行后,显示结果如下:
2012-03-19 16:40:04.345 Sample01[41713:1307] Tom and Jerry.
2012-03-19 16:40:04.350 Sample01[41713:1307] property:age
2012-03-19 16:40:04.352 Sample01[41713:1307] property_getAttributes:Ti,Vage
2012-03-19 16:40:04.354 Sample01[41713:1307] property:name
2012-03-19 16:40:04.355 Sample01[41713:1307] property_getAttributes:T@"NSString",C,N,Vname
关于属性的特性参数可以参考官方文档说明:
You can use the
The string starts with a
the name of the backing instance variable. Between these, the attributes are specified by the following descriptors, separated by commas:
Table 7-1 Declared property type encodings
参考网上各种资料,Object c++的反射主要依靠下面的2个函数。
NSClassFromString
NSSelectorFromString
下面直接摆上例子,一目了然。
(一)通过一个字符串来创建对象并调用对象中的方法。
文件:Member.h
Cpp代码
// Member.h
#import <Foundation/Foundation.h>
@interface Member : NSObject {
NSString *name;
int age;
}
@property (nonatomic,copy) NSString *name;
@property int age;
@end
// Member.h #import <Foundation/Foundation.h> @interface Member : NSObject { NSString *name; int age; } @property (nonatomic,copy) NSString *name; @property int age; @end
文件Member.m
Cpp代码
// Member.m #import "Member.h" @implementation Member @synthesize name,age; @end
// Member.m #import "Member.h" @implementation Member @synthesize name,age; @end
测试代码文件Sample01.m:
Cpp代码
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//定义类名
NSString *className=@"Member";
//定义方法名
//注意:方法名后面要根据参数来设置,这里的setName:,表示setName
// 方法后面有1个参数
NSString *methodName=@"setName:";
//取得类并分配内存和初始化
id obj=[[NSClassFromString(className) alloc] init];
//调用类方法
[obj performSelector: NSSelectorFromString(methodName) withObject:@"Tom and Jerry."];
//显示
NSLog(@"%@",[obj name]);
[pool drain];
return 0;
}
#import <Foundation/Foundation.h> int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; //定义类名 NSString *className=@"Member"; //定义方法名 //注意:方法名后面要根据参数来设置,这里的setName:,表示setName // 方法后面有1个参数 NSString *methodName=@"setName:"; //取得类并分配内存和初始化 id obj=[[NSClassFromString(className) alloc] init]; //调用类方法 [obj performSelector: NSSelectorFromString(methodName) withObject:@"Tom and Jerry."]; //显示 NSLog(@"%@",[obj name]); [pool drain]; return 0; }
代码执行后,显示如下:
2012-03-16 17:41:31.962 Sample01[39762:1307] Tom and Jerry.
由上面例子发现:
(1)在反射时,不需要使用import引入要反射的类;
(2)在定义反射类方法名时要注意后面的冒号,必须根据参数数量和原类方法名设置。
(二)通过字符串获取类的全部属性。
对上面的例子进行调整,如下面代码:(注意:在头部要引入头文件 objc/runtime.h)
Cpp代码
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//定义类名
NSString *className=@"Member";
//定义方法名
//注意:方法名后面要根据参数来设置,这里的setName:,表示setName
// 方法后面有1个参数
NSString *methodName=@"setName:";
//取得类并分配内存和初始化
id obj=[[NSClassFromString(className) alloc] init];
//调用类方法
[obj performSelector: NSSelectorFromString(methodName) withObject:@"Tom and Jerry."];
//显示
NSLog(@"%@",[obj name]);
//定义类属性的数量
unsigned propertyCount;
//获取对象的全部属性并循环显示属性名称和属性特性参数
objc_property_t *properties = class_copyPropertyList([obj class],&propertyCount);
for(int i=0;i<propertyCount;i++){
objc_property_t prop=properties[i];
NSLog(@"property:%s",property_getName(prop));
NSLog(@"property_getAttributes:%s",property_getAttributes(prop));
}
[pool drain];
return 0;
}
#import <Foundation/Foundation.h> #import <objc/runtime.h> int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; //定义类名 NSString *className=@"Member"; //定义方法名 //注意:方法名后面要根据参数来设置,这里的setName:,表示setName // 方法后面有1个参数 NSString *methodName=@"setName:"; //取得类并分配内存和初始化 id obj=[[NSClassFromString(className) alloc] init]; //调用类方法 [obj performSelector: NSSelectorFromString(methodName) withObject:@"Tom and Jerry."]; //显示 NSLog(@"%@",[obj name]); //定义类属性的数量 unsigned propertyCount; //获取对象的全部属性并循环显示属性名称和属性特性参数 objc_property_t *properties = class_copyPropertyList([obj class],&propertyCount); for(int i=0;i<propertyCount;i++){ objc_property_t prop=properties[i]; NSLog(@"property:%s",property_getName(prop)); NSLog(@"property_getAttributes:%s",property_getAttributes(prop)); } [pool drain]; return 0; }
代码执行后,显示结果如下:
2012-03-19 16:40:04.345 Sample01[41713:1307] Tom and Jerry.
2012-03-19 16:40:04.350 Sample01[41713:1307] property:age
2012-03-19 16:40:04.352 Sample01[41713:1307] property_getAttributes:Ti,Vage
2012-03-19 16:40:04.354 Sample01[41713:1307] property:name
2012-03-19 16:40:04.355 Sample01[41713:1307] property_getAttributes:T@"NSString",C,N,Vname
关于属性的特性参数可以参考官方文档说明:
Property Type String
You can use the property_getAttributesfunction to discover the name, the
@encodetype string of a property, and other attributes of the property.
The string starts with a
Tfollowed by the
@encodetype and a comma, and finishes with a
Vfollowed by
the name of the backing instance variable. Between these, the attributes are specified by the following descriptors, separated by commas:
R | The property is read-only (readonly). |
C | The property is a copy of the value last assigned (copy). |
& | The property is a reference to the value last assigned (retain). |
N | The property is non-atomic (nonatomic). |
G<name> | The property defines a custom getter selector name. The name follows the G(for example, GcustomGetter,). |
S<name> | The property defines a custom setter selector name. The name follows the S(for example, ScustomSetter:,). |
D | The property is dynamic (@dynamic). |
W | The property is a weak reference (__weak). |
P | The property is eligible for garbage collection. |
t<encoding> | Specifies the type using old-style encoding. |
相关文章推荐
- object c++如何实现反射机制
- object c++如何实现反射机制
- C++ 如何用宏实现反射机制
- C++实现 反射 机制( 即根据 类名 创建 类实例)Create C++ Object Dynamically
- C++实现反射机制(二)
- C++反射机制的实现(转)
- 杂货边角(8):C++实现反射机制
- java利用反射实现Object-c中的KVC机制
- C++实现反射机制(二)
- C++ 实现反射机制
- C++ 实现反射机制
- 一个新的对象创建机制的思考--C++下实现类似于Java的对象管理机制及反射
- C++反射机制的实现
- C++反射机制的实现
- C++反射机制:可变参数模板实现C++反射
- 实现C++ 枚举反射机制
- C++反射机制的实现
- 如何利用反射机制实现前台页面共用一个servlet文件
- C++反射机制的实现
- C++实现反射机制