一、 简介

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

<span style="font-size:18px;">#import <objc/runtime.h>
</span>

当我接触一样新的知识的时候,我比较喜欢先查看一下头文件,看看头文件里给我们提供了哪些接口。由于篇幅限制,我就偷个懒不往这里粘贴代码了。当我们查看runtime.h的时候,我们会发现,其实runtime是很有条理的。头文件主要给我们提供了4个类型(当然不止4种)的函数供我们使用。这4个类型分别以class、 method 、ivar、 objc加下划线开头。例如:

<span style="font-size:14px;">const char *object_getClassName(id obj)//获取对象的类名</span>
<span style="font-size:14px;">Ivar *class_copyIvarList(Class cls, unsigned int *outCount)//获取类的变量列表</span>
<span style="font-size:12px;"><span style="font-family: Menlo; color: rgb(4, 51, 255);">unsigned</span><span style="font-family: Menlo;"> </span><span style="font-family: Menlo; color: rgb(4, 51, 255);">int</span><span style="font-family: Menlo;"> method_getNumberOfArguments(</span><span style="font-family: Menlo; color: rgb(52, 149, 175);">Method</span><span style="font-family: Menlo;"> m)//获取函数变量的个数</span></span>
<p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo;"></p><p style="margin-top: 0px; margin-bottom: 0px; font-family: Menlo;"><span style="font-size:12px;"><span style="color: rgb(4, 51, 255);">void</span> objc_setAssociatedObject(<span style="color: rgb(4, 51, 255);">id</span> object, <span style="color: rgb(4, 51, 255);">const</span> <span style="color: rgb(4, 51, 255);">void</span> *key, <span style="color: rgb(4, 51, 255);">id</span> value, <span style="color: rgb(52, 149, 175);">objc_AssociationPolicy</span> policy)//建立关联</span></p>

二、runtime 大招


     2.1)为已有的类添加属性

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

#import <Foundation/Foundation.h>

@interface DZLPerson : NSObject

@property(nonatomic,weak)NSString *name;
@property(nonatomic,assign)NSInteger age; @end

但是,后来我们发现,仅仅这两个属性是不够描述的,我们还需要添加一个job属性来描述一个人。因此我们想到了用分类来添加属性。

<span style="font-size:14px;">#import "DZLPerson.h"

@interface DZLPerson (Job)

@property(nonatomic,copy)NSString* job;

@end</span><span style="font-size:18px;">
</span>

但是事情往往没有那么简单,当我们运行程序时就会发现,程序崩溃了。

<span style="font-size:14px;">- (void)viewDidLoad
{
[super viewDidLoad];
DZLPerson *p=[[DZLPerson alloc] init];
p.age=25;
p.name=@"皮拉夫大王";
p.job=@"ios"; NSLog(@"%@",p); }</span>
<span style="font-size:14px;">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'</span>

程序提示我们:找不到setJob方法。这是理所当然的,因为系统不能为我们自动添加成员变量了,也就不知道该如何帮我们创建setter 和getter方法了。但是我们可以通过runtime来添加属性,使我们能够像真正的修改了Person类那样使用新的属性job。

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

<span style="font-size:14px;">#import "DZLPerson+Job.h"
#import <objc/runtime.h> static NSString *key=@"dzl"; //利用静态变量地址唯一不变的特性 @implementation DZLPerson (Job) -(void)setJob:(NSString *)job
{ objc_setAssociatedObject(self, &key, job, OBJC_ASSOCIATION_COPY);
} -(NSString *)job
{
return objc_getAssociatedObject(self, &key);
} @end</span>

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

通过关联引用我们就添加上了job 属性(叫属性有点不准确,如果可以的话我还是愿意叫它伪成员变量)。

IOS高级开发 runtime(一)的更多相关文章

  1. iOS 高级开发 runtime(三)

    三 .动态添加方法 我们可以通过runtime动态地添加方法.那么到底啥叫动态添加方法呢?动态添加方法就是当我们程序运行时才知道我们应该调用哪个方法.我们首先需要了解这一点,当我们编写完一段代码后,我 ...

  2. IOS 高级开发 runtime(二)

    二.移魂大法 使用runtime还可以交换两个函数.先贴上代码和执行结果. #import <Foundation/Foundation.h> @interface DZLPerson : ...

  3. (转发)IOS高级开发~Runtime(四)

    用C代替OC: #import <objc/runtime.h> #import <objc/message.h> #import <stdio.h> extern ...

  4. (转发)IOS高级开发~Runtime(三)

    11.系统类的方法实现部分替换 - (void) methodExchange { Method m1 = class_getInstanceMethod([NSStringclass],@selec ...

  5. (转发)IOS高级开发~Runtime(二)

    一些公用类: @interface ClassCustomClass :NSObject{ NSString *varTest1; NSString *varTest2; NSString *varT ...

  6. (转发)IOS高级开发~Runtime(一)

    IOS高级开发-Runtime(一) IOS高级开发-Runtime(二) IOS高级开发-Runtime(三) IOS高级开发-Runtime(四) 一些公用类: @interface Custom ...

  7. IOS高级开发之多线程(四)NSOperation

    1.什么是NSOperation,NSOperationQueue? NSOperation是一个抽象的基类,表示一个独立的计算单元,可以为子类提供有用且线程安全的建立状态,优先级,依赖和取消等操作. ...

  8. IOS高级开发~Runtime(一)

    #import <Foundation/Foundation.h> @interface CustomClass : NSObject -(void)fun1; @end @interfa ...

  9. IOS高级开发~Runtime(二)

    #import <Foundation/Foundation.h> @interface CustomClass : NSObject { NSString *varTest1; NSSt ...

随机推荐

  1. 关于NSLocalizedString(@"Foo %@",nil)

    NSLocalizedString(@"Foo %@",nil) 这句话实际上是在多语言文件中寻找一个key为“Foo %@”的文字,千万不要把这个和[NSString strin ...

  2. Java笔记(二十九)……网络编程

    概述 网络模型 网络通讯的要素 ip地址:网络中设备的标识符 端口:用于标识同一台设备上不同的进程,有效端口:0~65535,其中0~1024是系统使用端口或者保留端口 TCP与UDP UDP特点: ...

  3. codevs 3160 最长公共子串(SAM)

    3160 最长公共子串   题目描述 Description 给出两个由小写字母组成的字符串,求它们的最长公共子串的长度. 输入描述 Input Description 读入两个字符串 输出描述 Ou ...

  4. Struts2使用拦截器完成权限控制示例

    http://aumy2008.iteye.com/blog/146952 Struts2使用拦截器完成权限控制示例 示例需求:    要求用户登录,且必须为指定用户名才可以查看系统中某个视图资源:否 ...

  5. Zend Studio 或者Eclipse下安装插件Spket(以Zend为例)

    1. Help>Install New Software... 2. 在Work With:后输入网址 http://www.agpad.com/update,点击Add 3. 输入Name:S ...

  6. algorithm@ Matrix fast power

    一. 什么是快速幂: 快速幂顾名思义,就是快速算某个数的多少次幂.其时间复杂度为 O(log₂N), 与朴素的O(N)相比效率有了极大的提高.一般一个矩阵的n次方,我们会通过连乘n-1次来得到它的n次 ...

  7. 阿里云服务器(CentOS)安装tomcat,jdk,布署J2EE项目

    1.使用Xshell登录服务器,当然你也可以使用其他软件登录服务器 2.Linux服务器挂载数据盘,具体参见视频教程(quote:"一般来说服务器的数据盘需要和系统盘分开,当系统出现故障后能 ...

  8. A Tour of Go Basic types

    Go's basic types are bool string int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr ...

  9. windows蓝屏代码大全及常见蓝屏解决方案

    对于以下的代码查询建议使用ctrl+F查询,而且很多蓝屏与黑屏的问题多是最近操作引起的,例如更新驱动,安装新的硬件.软件--把相关的配置调到最近的正常状况大多可以解决,确实不行时方可考虑重装系统,解决 ...

  10. Android Fragment 生命周期

    启动的事件触发顺序 F Fragmeent A Activity onAttach(F) onAttachFragment(A) onCreate(F) onCreateView(F) onActiv ...