欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

IOS 中runtime使用方法整理

程序员文章站 2024-02-13 19:24:22
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]);
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!