做iOS的朋友都知道或听说runtime,这个东西很像java的反射机制,但功能远胜于java的反射。通过runtime我们可以动态的向一个类中添加属性、成员变量、方法,以及对其进行读写访问。
新建两个类ClassOne和ClassTwo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#import <Foundation/Foundation.h> @interface ClassOne : NSObject{ NSString *_publicVar1; NSString *_publicVar2; } @property(nonatomic,copy) NSString *publicProperty1; @property(nonatomic,copy) NSString *publicProperty2; - ( void ) testClassOneWithArg1:(NSString *)arg1; @end #import "ClassOne.h" @interface ClassOne() @property(nonatomic,copy) NSString *privateProperty1; @property(nonatomic,copy) NSString *privateProperty2; @end @implementation ClassOne{ NSString *_privateVar1; NSString *_privateVar2; } - ( void )testClassOneWithArg1:(NSString *)arg1{ NSLog(@ "this is CalssOne, arg1:%@" ,arg1); } - ( void )testClassOneWithArg1:(NSString *)arg1 arg2:arg2{ NSLog(@ "this is CalssOne, arg1:%@ arg2:%@" ,arg1,arg2); } @end |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#import <Foundation/Foundation.h> @interface ClassTwo : NSObject - ( void ) testClassTwoWithArg1:(NSString *)arg1 arg2:(NSString *)arg2; @end #import "ClassTwo.h" @implementation ClassTwo - ( void )testClassTwoWithArg1:(NSString *)arg1 arg2:(NSString *)arg2{ NSLog(@ "this is ClassTwo arg1:%@,arg2:%@" ,arg1,arg2); } @end |
1.拷贝对象
1
2
|
ClassOne *one = [ClassOne new ]; id onec1 = object_copy(one, sizeof (one)); |
2.给类添加方法
1
2
3
4
5
6
7
8
9
|
ClassOne *one = [ClassOne new ]; class_addMethod([ClassOne class ], @selector(testClassOneWithArg1:arg2:arg3:), (IMP)testClassOne , "i@:@@@" ); [one testClassOneWithArg1:@ "arg1" arg2:@ "arg2" arg3:@ "arg3" ]; //方法对应的C函数 int testClassOne(id self,SEL _cmd, NSString *arg1,NSString *arg2,NSString *arg3){ NSLog(@ "this is a test function add to ClassOne as a methad with arg1:%@ arg2:%@ and arg3:%@" ,arg1,arg2,arg3); return 10; } |
3.添加属性(方式一)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
//属性类型 objc_property_attribute_t type = { "T" , "@\"NSString\"" }; //访问类型 objc_property_attribute_t ownership = { "C" , "" }; //对应成员变量名称 objc_property_attribute_t backingivar = { "V" , "_testPropertyName" }; objc_property_attribute_t attrs[] = { type, ownership, backingivar }; class_addProperty([ClassOne class ], "testPropertyName" , attrs, 3); class_addMethod([ClassOne class ], @selector(testPropertyName), (IMP)testPropertyNameGetter , "@:@@" ); class_addMethod([ClassOne class ], @selector(setTestPropertyName:), (IMP)testPropertyNameSetter, "v:@@@" ); //属性对应的Getter方法 NSString* testPropertyNameGetter(id self,SEL _cmd){ Ivar ivar = class_getInstanceVariable([ClassOne class ], "_testPropertyName" ); return object_getIvar(self, ivar); } //属性对应的Setter方法 void testPropertyNameSetter(id self,SEL _cmd,NSString *testPropertyNameValue){ Ivar ivar = class_getInstanceVariable([ClassOne class ], "_testPropertyName" ); object_setIvar(self, ivar, testPropertyNameValue); } |
4.添加属性(方式2)
1
2
3
4
|
ClassOne *one = [ClassOne new ]; objc_setAssociatedObject(one, "objTag" , @ "value" , OBJC_ASSOCIATION_COPY); NSString *value = objc_getAssociatedObject(one, "objTag" ); NSLog(@ "通过Associate设置:%@" ,value); |
5.获取类的名称
1
2
3
|
ClassOne *one = [ClassOne new ]; const char *className = object_getClassName(one); NSLog(@ "className:%@" ,[NSString stringWithUTF8String:className]); |
6.获取一个类的所有方法
1
2
3
4
5
6
7
|
UInt count; Method *methods = class_copyMethodList([ClassOne class ], &count); for ( int i = 0; i < count; i++) { Method method = methods[i]; SEL sel = method_getName(method); NSLog(@ "方法名:%@" ,NSStringFromSelector(sel)); } |
7.获取一个类的所有属性
1
2
3
4
5
6
7
8
9
|
uint propertyCount; objc_property_t *ps = class_copyPropertyList([ClassOne class ], &propertyCount); for (uint i = 0; i < propertyCount; i++) { objc_property_t property = ps[i]; const char *propertyName = property_getName(property); const char *propertyAttributes = property_getAttributes(property); NSLog(@ "propertyName:%@" ,[NSString stringWithUTF8String:propertyName]); NSLog(@ "propertyAttributes:%@" ,[NSString stringWithUTF8String:propertyAttributes]); } |
8.获取类的所有成员变量
1
2
3
4
5
6
7
|
uint ivarCount; Ivar *ivars = class_copyIvarList([ClassOne class ], &ivarCount); for (uint i = 0; i < ivarCount; i++) { Ivar ivar = ivars[i]; const char *ivarName = ivar_getName(ivar); NSLog(@ "ivarName:%@" ,[NSString stringWithUTF8String:ivarName]); } |
9.获得成员变量类型
1
2
3
4
5
6
7
8
|
uint ivarCount; Ivar *ivars = class_copyIvarList([ClassOne class ], &ivarCount); for (uint i = 0; i < ivarCount; i++) { Ivar ivar = ivars[i]; const char *ivarName = ivar_getName(ivar); const char *type = ivar_getTypeEncoding(ivar); NSLog(@ "ivarName=%@,type=%@" ,[NSString stringWithUTF8String:ivarName],[NSString stringWithUTF8String:type]); } |
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
原文链接:http://blog.csdn.net/mr_yong/article/details/50330151