做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