IOS 中runtime使用方法整理
程序员文章站
2023-12-20 12:42:04
ios 中runtime使用方法整理
做ios的朋友都知道或听说runtime,这个东西很像java的反射机制,但功能远胜于java的反射。通过runtime我们可以动态...
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]); }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!