码迷,mamicode.com
首页 > 移动开发 > 详细

IOS高级开发 runtime(1)

时间:2015-04-15 11:19:44      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:

一、 简介

IOS 开发中灵活使用runtime 会提高我们的程序性能和开发速度。要想使用runtime,首先要引入系统的头文件。

#import <objc/runtime.h> 

当我们查看runtime.h的时候,我们会发现,其实runtime是很有条理的

const char *object_getClassName(id obj)                     //获取对象的类

Ivar *class_copyIvarList(Class cls, unsigned int *outCount) //获取类的变量列表

unsigned method_getNumberOfArguments(Method m)              //获取函数变量的个数

属性 其实就是get/set 方法。我们可以使用  objc_setAssociatedObject/objc_getAssociatedObject  实现 动态向类中添加 方法

objc_setAssociatedObject 需要四个参数:源对象,关键字,关联的对象和一个关联策略。
//1 源对象alert
//2 关键字 唯一静态变量key associatedkey
//3 关联的对象 sender
//4 关键策略  OBJC_ASSOCIATION_RETAIN_NONATOMIC

通过 objc_getAssociatedObject获取关联对象

使用函数objc_removeAssociatedObjects可以断开所有关联。通常情况下不建议使用这个函数,因为他会断开所有关联。只有在需要把对象恢复到“原始状态”的时候才会使用这个函数。

二、runtime 大招


     2.1)为已有的类添加属性

OC语法允许我们通过继承或者添加分类(category)修改(也不能说修改,就是改造成我们需要的类)已有的类。继承在这里不是我们想讨论的,主要是想说一下分类。分类可以允许我们添加属性(不会生成get和set方法,需要手动添加)和方法,但是却不允许我们添加成员变量。但是有些时候,我们需要添加一个变量来扩充这个类,比如:我有一个类Person类,带有age 和name 属性

  1. #import <Foundation/Foundation.h>  
  2.   
  3. @interface zzPerson : NSObject  
  4.   
  5. @property(nonatomic,weak)NSString *name;  
  6. @property(nonatomic,assign)NSInteger age;  
  7.   
  8. @end  
但是,后来我们发现,仅仅这两个属性是不够描述的,我们还需要添加一个job属性来描述一个人。因此我们想到了用分类来添加属性。

  1. #import "zzPerson.h"  
  2.   
  3. @interface zzPerson (Job)  
  4.   
  5. @property(nonatomic,copy)NSString* job;  
  6.   
  7. @end
 但是事情往往没有那么简单,当我们运行程序时就会发现,程序崩溃了。
  1. - (void)viewDidLoad  
  2. {  
  3.     [super viewDidLoad];  
  4.     DZLPerson *p=[[zzPerson alloc] init];  
  5.     p.age=25;  
  6.     p.name=@"皮拉夫大王";  
  7.     p.job=@"ios";  
  8.       
  9.     NSLog(@"%@",p);  
  10.   
  11. }
  12. 2015-04-10 00:05:50.591 runtime讲解[4197:209347] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException‘, reason‘-[DZLPerson setJob:]: unrecognized selector sent to instance 0x7fe809f24790‘  
程序提示我们:找不到setJob方法。这是理所当然的,因为系统不能为我们自动添加成员变量了,也就不知道该如何帮我们创建setter 和getter方法了。但是我们可以通过runtime来添加属性,使我们能够像真正的修改了Person类那样使用新的属性job。

首先在分类的.m 中导入runtime头文件,然后重写job的getter 和setter 方法。

  1. #import "zzPerson+Job.h"  
  2. #import <objc/runtime.h>  
  3.   
  4.   
  5. static NSString *key=@"zz"//利用静态变量地址唯一不变的特性  
  6.   
  7. @implementation zzPerson (Job)  
  8.   
  9. -(void)setJob:(NSString *)job  
  10. {  
  11.   
  12.     objc_setAssociatedObject(self, &key, job, OBJC_ASSOCIATION_COPY);  
  13. }  
  14.   
  15. -(NSString *)job  
  16. {  
  17.     return objc_getAssociatedObject(self, &key);  
  18. }  
  19.   
  20. @end   

 建立关联引用,将这个对象和我们所利用的唯一不变的地址进行关联,而关联则是job属性,这样的话由于建立关联的对象存在,所进行关联的键唯一,所以我们的属性也被唯一保存了,如同保存在对象自身上一样。



IOS高级开发 runtime(1)

标签:

原文地址:http://blog.csdn.net/lin1986lin/article/details/45056357

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!