设为首页 加入收藏

TOP

Runtime的几个小例子(含Demo)(二)
2017-10-13 10:32:58 】 浏览:4635
Tags:Runtime 例子 Demo
构体指针,包含了变量名、变量类型等信息。

可以看到,私有属性name能够访问到了。 在有些项目中,为了对某些私有属性进行隐藏,某些.h文件中没有出现相应的显式创建,而是如上面的person类中,在.m中进行私有创建,但是我们可以通过runtime这个有效的方法,访问到所有包括这些隐藏的私有变量。

拓展

①class_copyIvarList能够获取一个含有类中所有成员变量的列表,列表中包括属性变量和实例变量。需要注意的是,如果如本例中,age返回的是"_age",但是如果在person.m中加入:

@synthesize age;

那么控制台第二行返回的是"(Name: age) ----- (Type:i) ;"(因为@property是生成了"_age",而@synthesize是执行了"@synthesize age = _age;",关于OC属性变量与实例变量的区别、@property、@synthesize的作用等具体的知识,有兴趣的童鞋可以自行了解。)

②如果单单需要获取属性列表的话,可以使用函数:class_copyPropertyList();只是返回的属性变量仅仅是“age”,做为实例变量的name是不被获取的。

而class_copyIvarList()函数则能够返回实例变量和属性变量的所有成员变量。

 

2.获取person类的所有方法

将第二个按钮关联到ViewController.h,添加行为并命名其方法为:“getAllMethod”:

- (IBAction)getAllMethod:(UIButton *)sender;   //获取所有方法

在ViewController.m中的实现如下:

/*2.获取person所有方法*/
- (IBAction)getAllMethod:(UIButton *)sender {
unsigned
int count;
//获取方法列表,所有在.m文件显式实现的方法都会被找到,包括setter+getter方法; Method *allMethods = class_copyMethodList([person class], &count); for(int i =0;i<count;i++) { //Method,为runtime声明的一个宏,表示对一个方法的描述 Method md = allMethods[i]; //获取SEL:SEL类型,即获取方法选择器@selector() SEL sel = method_getName(md); //得到sel的方法名:以字符串格式获取sel的name,也即@selector()中的方法名称 const char *methodname = sel_getName(sel); NSLog(@"(Method:%s)",methodname); } }

点击按钮后,控制台输出:

2016-05-19 17:05:19.880 runtime运行时[14054:678124] (Method:func1) 2016-05-19 17:05:19.881 runtime运行时[14054:678124] (Method:func2) 2016-05-19 17:05:19.881 runtime运行时[14054:678124] (Method:setAge:) 2016-05-19 17:05:19.881 runtime运行时[14054:678124] (Method:age) 2016-05-19 17:05:19.881 runtime运行时[14054:678124] (Method:.cxx_destruct) 2016-05-19 17:05:19.882 runtime运行时[14054:678124] (Method:description) 2016-05-19 17:05:19.882 runtime运行时[14054:678124] (Method:init)

控制台输出了包括set和get等方法名称。【备注:.cxx_destruct方法是关于系统自动内存释放工作的一个隐藏的函数,当ARC下,且本类拥有实例变量时,才会出现;】

分析Method是一个指向objc_method结构体指针表示对类中的某个方法的描述。在API中的定义:

typedef struct objc_method *Method;

objc_method结构体如下

truct objc_method { SEL method_name OBJC2_UNAVAILABLE; char *method_types OBJC2_UNAVAILABLE; IMP method_imp OBJC2_UNAVAILABLE; } 
  • method_name :方法选择器@selector(),类型为SEL。 相同名字的方法下,即使在不同类中定义,它们的方法选择器也相同。
  • method_types:方法类型,是个char指针,存储着方法的参数类型和返回值类型。
  • method_imp:指向方法的具体实现的指针,数据类型为IMP,本质上是一个函数指针。 在第五个按钮行为“增加一个方法”部分会提到。

SEL:数据类型,表示方法选择器,可以理解为对方法的一种包装。在每个方法都有一个与之对应的SEL类型的数据,根据一个SEL数据“@selector(方法名)”就可以找到对应的方法地址,进而调用方法。

因此可以通过:获取Method结构体->得到SEL选择器名称->得到对应的方法名,这样的方式,便于认识OC中关于方法的定义。

 

 

3.改变person对象的私有变量name的值.

将第三个按钮关联到ViewController.h,添加行为并命名其方法为:“changeVariable”:

- (IBAction)changeVariable:(UIButton *)sender;//改变其中name变量

在ViewController.m中创建一个person对象,记得初始化

@implementation ViewController
{
    person *per;  //创建一个person实例
}
- (void)viewDidLoad {
    [super viewDidLoad];
    per = [[person alloc]init]; //记得要初始化...不然后果自己尝试下
}

 

在ViewController.m中的实现如下:

/*3.改变person的name变量属性*/
- (IBAction)changeVariable:(UIButton *)sender {
NSLog(
@"改变前的person:%@",per); unsigned int count = 0; Ivar *allList = class_copyIvarList([person class], &count); Ivar ivv = allList[0]; //从第一个例子getAllVariable中输出的控制台信息,我们可以看到name为第一个实例属性; object_set
首页 上一页 1 2 3 4 下一页 尾页 2/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇iOS UIScrollView的使用 下一篇iOS开发UI篇-tableView在编辑状态..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目