IOS 中runtime使用方法整理
做iOS的朋友都知道或听说runtime,这个东西很像java的反射机制,但功能远胜于java的反射。通过runtime我们可以动态的向一个类中添加属性、成员变量、方法,以及对其进行读写访问。
新建两个类ClassOne和ClassTwo
#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
#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.拷贝对象
ClassOne *one = [ClassOne new];id onec1 = object_copy(one,sizeof(one));
2.给类添加方法
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.添加属性(方式一)
//属性类型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)
ClassOne *one = [ClassOne new];objc_setAssociatedObject(one, "objTag", @"value", OBJC_ASSOCIATION_COPY);NSString *value = objc_getAssociatedObject(one, "objTag");NSLog(@"通过Associate设置:%@",value);
5.获取类的名称
ClassOne *one = [ClassOne new];const char *className = object_getClassName(one);NSLog(@"className:%@",[NSString stringWithUTF8String:className]);
6.获取一个类的所有方法
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.获取一个类的所有属性
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.获取类的所有成员变量
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.获得成员变量类型
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]);}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
新闻热点
疑难解答